/*
 * test.c
 *
 *  Created on: 22 Apr 2015
 *      Author: Niall.Donovan
 */
#include <api_oam_sdk/loopback/src/lb_support.h>
#include <api_oam_sdk/mep/inc/mep.h>
#include <api_oam_sdk/metroam_hal/inc/mr_hal.h>
#include <api_oam_sdk/performance_monitoring/inc/pm_dm.h>
#include <api_oam_sdk/rmep_db/inc/rmep_db.h>
#include <api_oam_sdk/service_activation/inc/rfc2544.h>
#include <api_oam_sdk/service_activation/inc/rfc2544.h>
#include <api_oam_sdk/service_activation/inc/y1564.h>
#include <api_oam_sdk/service_cos/src/svc_cos_types.h>
#include <api_oam_sdk/service_l2cp/src/svc_l2cp_types.h>
#include <api_oam_sdk/table_access/inc/table_access.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>

#include "egl_types.h"
#include "egl_assert.h"
#include "egl_log.h"
#include "osal.h"

static uint16_t				log_handle				= 0;		// handle used to log messages for this module
static bool					testInitialised			= false;

static bool basic_createMDTest(bool recursiveCall)
{
    mdIndex_t			mdIndex;
    mdNameType_t		mdType;
    mdName_t			mdName;
    mdLevel_t 			mdLevel;
    int					retVal;
    mdMibInfo_t 		mdMibInfo;
    networkAddress_t 	faultAlarmNetAddr;
    ts_printf("In Basic MD Creation function1\n\r");
    if(!recursiveCall)
    {
        // Read Empty list
        mdIndex = mdReadList(0);
        ts_printf("In Basic MD Creation function1-1\n\r");
        if (mdIndex != 0)
        {
            DO_LOG_DEBUG(log_handle, "mdReadList returned non zero value when 0 was expected");
            //VRts_printf("In Basic MD Creation function1-2\n\r");
            return false;
        }
    }
    ts_printf("In Basic MD Creation function2\n\r");
    // Read 'Next MD Index'
    mdIndex = mdListReadNextMdIndex();
    if (!recursiveCall)		// If this test is included it's not possible to call this function repeatedly
    {
        if (mdIndex != 1)
        {
            DO_LOG_DEBUG(log_handle, "mdListReadNextMdIndex returned a value other than 1");
            return false;
        }
    }
    //VRts_printf("In Basic MD Creation function3\n\r");
    // Use Illegal MD Index
    mdLevel = 1;
    mdType = md_characterString;
    retVal = mdCreate(0, mdName, mdType, mdLevel);
    if (retVal != -1)
    {
        DO_LOG_DEBUG(log_handle, "mdCreate should have returned -1 (invalid MD index) but the return value was %d",retVal);
        return false;
    }
    //VRts_printf("In Basic MD Creation function4\n\r");
#if 0 // this test is no longer relevant
    // Use Illegal MD Index
    retVal = mdCreate(mdListReadNextMdIndex() + 1, mdName, mdType, mdLevel);
    if (retVal != -1)
    {
        DO_LOG_DEBUG(log_handle, "mdCreate should have returned -1 (invalid MD index) but the return value was %d",retVal);
        return false;
    }
#endif

    // Use Illegal level
    mdLevel = 8;
    retVal = mdCreate(mdIndex, mdName, mdType, mdLevel);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "mdCreate should have returned 3 (invalid mdLevel) but the return value was %d",retVal);
        return false;
    }
    //VRts_printf("In Basic MD Creation function5\n\r");
    // Use Illegal type
    mdLevel = 1;
    mdType = 10;
    retVal = mdCreate(mdIndex, mdName, mdType, mdLevel);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "mdCreate should have returned 1 (invalid MD name/type) but the return value was %d",retVal);
        return false;
    }
    //VRts_printf("In Basic MD Creation function6\n\r");
    // Use Illegal string values
    mdLevel = 1;
    mdType = md_characterString;
    strcpy(mdName,"TEST_MD_L1.;?*");
    mdName[12] = 12;
    retVal = mdCreate(mdIndex, mdName, mdType, mdLevel);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "mdCreate should have returned 1 (invalid MD name/type) but the return value was %d",retVal);
        return false;
    }
    //VRts_printf("In Basic MD Creation function7\n\r");
    // Use good values
    mdType = md_characterString;
    mdLevel = 1;
    sprintf(mdName, "MD_L1_%lu",mdIndex);
    retVal = mdCreate(mdIndex, mdName, mdType, mdLevel);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "mdCreate failed to create a MD when expected to succeed. Return value was %d",retVal);
        return false;
    }
    ts_printf("In Basic MD Creation function8\n\r");
    // Use Illegal MD Index
    retVal = mdRead(0, &mdMibInfo, &faultAlarmNetAddr);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "mdRead should have returned 1 (Unknown MD Index) but the return value was %d",retVal);
        return false;
    }

    // Use NULL parameters
    retVal = mdRead(mdIndex, NULL, NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "mdRead should have returned 2 but the return value was %d",retVal);
        return false;
    }
    ts_printf("In Basic MD Creation function9\n\r");
    // Use NULL alarm address parameter
    retVal = mdRead(mdIndex, &mdMibInfo, NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "mdRead should have returned 2 (Operation accepted) but the return value was %d",retVal);
        return false;
    }

    // test all the return parameters
    if (mdMibInfo.type != mdType)
    {
        DO_LOG_DEBUG(log_handle, "mdRead gave mdType as %d but expected %d",mdMibInfo.type, mdType);
        return false;
    }

    if (strcmp(mdMibInfo.name,mdName) != 0)
    {
        DO_LOG_DEBUG(log_handle, "mdRead gave MD Name as '%s' but expected '%s'",mdMibInfo.name, mdName);
        return false;
    }

    if (mdMibInfo.level != mdLevel)
    {
        DO_LOG_DEBUG(log_handle, "mdRead gave mdLevel as %d but expected %d",mdMibInfo.level, mdLevel);
        return false;
    }

    if (mdMibInfo.maNextMibIdx != 1)
    {
        DO_LOG_DEBUG(log_handle, "mdRead gave maNextMibIdx as %d but expected 1",mdMibInfo.maNextMibIdx);
        return false;
    }

    if (mdMibInfo.mhfCreation != md_defMHFnone)
    {
        DO_LOG_DEBUG(log_handle, "mdRead gave mhfCreation as %d but expected %d",mdMibInfo.mhfCreation, md_defMHFnone);
        return false;
    }

    if (mdMibInfo.mhfIdPermission != md_sendIdNone)
    {
        DO_LOG_DEBUG(log_handle, "mdRead gave mhfIdPermission as %d but expected %d",mdMibInfo.mhfIdPermission, md_sendIdNone);
        return false;
    }

    if (!recursiveCall)		// This test prevents repeated calls of this function to succeed
    {
        // Read the MD list to confirm there is a new entry at the correct index
        mdIndex = mdReadList(0);
        if (mdIndex != 1)
        {
            DO_LOG_DEBUG(log_handle, "mdReadList returned %d but a value of 1 was expected",mdIndex);
            return false;
        }
    }

    // test to see if the MD index is valid (test validation function)
    if (mdIsMdMibIdxValid(mdIndex) == false)
    {
        DO_LOG_DEBUG(log_handle, "mdIsMdMibIdxValid returned false but a value of true was expected");
        return false;
    }

    // Test all write combinations...
    mdMhfCreation_t 	mdMhfCreation;
    mdMhfIdPermission_t	mdMhfIdPermission;

    // Try to write to illegal MD index
    retVal = mdWrite(0, mdParam_mdMhfCreation, &mdMhfCreation);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "mdWrite returned %d but a value of 1 was expected",retVal);
        return false;
    }

    // Try to write to an Illegal parameter
    retVal = mdWrite(mdIndex, 4, &mdMhfCreation);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "mdWrite returned %d but a value of 2 was expected",retVal);
        return false;
    }

    // Try to write an Illegal (NULL) parameter value
    retVal = mdWrite(mdIndex, mdParam_mdMhfCreation, NULL);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "mdWrite returned %d but a value of 3 was expected",retVal);
        return false;
    }

    // Try to write an Illegal parameter value
    mdMhfCreation = 6;
    retVal = mdWrite(mdIndex, mdParam_mdMhfCreation, &mdMhfCreation);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "mdWrite returned %d but a value of 3 (invalid param value) was expected",retVal);
        return false;
    }

    // Try to write a valid parameter and value
    mdMhfCreation = md_defMHFdefault;
    retVal = mdWrite(mdIndex, mdParam_mdMhfCreation, &mdMhfCreation);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "mdWrite returned %d but a value of 4 (Operation Accepted) was expected",retVal);
        return false;
    }

    // Try to write a valid parameter and value
    mdMhfIdPermission = md_sendIdChassis;
    retVal = mdWrite(mdIndex, mdParam_mdMhfIdPermission, &mdMhfIdPermission);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "mdWrite returned %d but a value of 4 (Operation Accepted) was expected",retVal);
        return false;
    }

    // Try to write a valid parameter and value to faultAlarmNetAddr
    faultAlarmNetAddr = 0x01020304;
    retVal = mdWrite(mdIndex, mdParam_mdFaultAlarmNetAddress, &faultAlarmNetAddr);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "mdWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    // Read back the recently written values
    networkAddress_t	rdFaultAlarmNetAddr;
    retVal = mdRead(mdIndex, &mdMibInfo, &rdFaultAlarmNetAddr);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "mdRead should have returned 2 (Operation accepted) but the return value was %d",retVal);
        return false;
    }

    // Verify the new values...
    if (mdMibInfo.mhfCreation != mdMhfCreation)
    {
        DO_LOG_DEBUG(log_handle, "mdRead gave mhfCreation as %d but expected %d",mdMibInfo.mhfCreation, mdMhfCreation);
        return false;
    }

    if (mdMibInfo.mhfIdPermission != mdMhfIdPermission)
    {
        DO_LOG_DEBUG(log_handle, "mdRead gave mhfIdPermission as %d but expected %d",mdMibInfo.mhfIdPermission, mdMhfIdPermission);
        return false;
    }

    if (rdFaultAlarmNetAddr != faultAlarmNetAddr)
    {
        DO_LOG_DEBUG(log_handle, "mdRead of faultAlarmNetAddr (%lu) did not return the value written (%lu)", rdFaultAlarmNetAddr, faultAlarmNetAddr);
        return false;
    }

    return true;
}

static bool basic_deleteMDTest(void)
{
    mdIndex_t	mdIndex;
    int			retVal;
    ts_printf("In Basic MD delete function\n\r");
    // Read the MD list to confirm there is a new entry at the correct index
    mdIndex = mdReadList(0);
    if (mdIndex == 0)
    {
        DO_LOG_DEBUG(log_handle, "mdReadList returned 0 but a non zero value was expected");
        return false;
    }

    // test to see if the MD index is valid (test validation function)
    if (mdIsMdMibIdxValid(mdIndex) == false)
    {
        DO_LOG_DEBUG(log_handle, "mdIsMdMibIdxValid returned false but a value of true was expected");
        return false;
    }

    // Use Illegal MD Index
    retVal = mdDelete(0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "mdDelete should have returned 1 (invalid MD index) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal MD Index
    retVal = mdDelete(mdListReadNextMdIndex());
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "mdDelete should have returned 1 (invalid MD index) but the return value was %d",retVal);
        return false;
    }

    retVal = mdDelete(mdIndex);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "mdDelete should have returned 2 (operation accepted) but the return value was %d",retVal);
        return false;
    }
    return true;
}

static bool basic_createMATest(bool recursiveCall)
{
    mdIndex_t			mdIndex;
    mdIndex_t			prevMdIndex;
    maIndex_t			maIndex;
    maNameType_t		maType;
    maName_t			maName;
    int					retVal;
    mdMibInfo_t			mdMibInfo;
    maNetInfo_t			maNetInfo;
    maCompInfo_t		maCompInfo;
    maMEFInfo_t			maMEFInfo;
    mepId_t				mepIdList[5];
    networkAddress_t 	faultAlarmNetAddr;
    networkAddress_t 	rdFaultAlarmNetAddr;
    uint16_t			vLanList[5] = {0,0,0,0,0};

    mdIndex = mdReadList(0);
    if (mdIndex == 0)
    {
        mdIndex = mdListReadNextMdIndex();
        retVal = mdCreate(mdIndex,"TEST_MD_1", md_characterString, 1);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "mdCreate failed to create a MD when expected to succeed. Return value was %d",retVal);
            return false;
        }
    }
    else
    {
        // Move to the last MD in the list
        while (mdIndex != 0)
        {
            prevMdIndex = mdIndex;
            mdIndex = mdReadList(mdIndex);
        }
        mdIndex = prevMdIndex;
    }

    // Use wrong MD index to Read MA list
    maIndex = maReadList(0, 0);
    if (maIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "maReadList returned non zero value when 0 was expected");
        return false;
    }

    if(!recursiveCall)
    {
        // Read the MA list - It is expected to be empty
        maIndex = maReadList(mdIndex, 0);
        if (maIndex != 0)
        {
            DO_LOG_DEBUG(log_handle, "maReadList returned non zero value when 0 was expected");
            return false;
        }
    }

    // Read 'Next MA Index'
    retVal = mdRead(mdIndex, &mdMibInfo, NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "mdRead should have returned 2 (Operation accepted) but the return value was %d",retVal);
        return false;
    }
    maIndex = mdMibInfo.maNextMibIdx;
    if (!recursiveCall)		// If this test is included it's not possible to call this function repeatedly
    {
        if (maIndex != 1)
        {
            DO_LOG_DEBUG(log_handle, "maNextMibIdx returned a value other than 1");
            return false;
        }
    }

    // Use Illegal MD Index
    maType = ma_characterString;
    retVal = maCreate(0,maIndex, maName, maType,vLanList,CTAG_TYPE,false);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "maCreate should have returned 1 (invalid MD index) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal MA Index
    maType = ma_characterString;
    retVal = maCreate(mdIndex,0, maName, maType,vLanList,CTAG_TYPE,false);
    if (retVal != -1)
    {
        DO_LOG_DEBUG(log_handle, "maCreate should have returned -1 (invalid MA index) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal MA Index
    maType = ma_characterString;
#if 0 // Test no longer applicable
    retVal = maCreate(mdIndex,maIndex+1, maName, maType,vLanList,CTAG_TYPE,false);
    if (retVal != -1)
    {
        DO_LOG_DEBUG(log_handle, "maCreate should have returned -1 (invalid MA index) but the return value was %d",retVal);
        return false;
    }
#endif

    // Use Illegal MA type
    maType = 10;
    retVal = maCreate(mdIndex,maIndex, maName, maType,vLanList,CTAG_TYPE,false);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "maCreate should have returned 2 (invalid MA name/type) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal MA Name
    maType = ma_characterString;
    strcpy(maName,"TEST_MA_L1.;?*");
    maName[12] = 12;
    retVal = maCreate(mdIndex,maIndex, maName, maType,vLanList,CTAG_TYPE,false);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "maCreate should have returned 2 (invalid MA name/type) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal tag type
    sprintf(maName, "MA_L1_%lu",maIndex);
    retVal = maCreate(mdIndex,maIndex, maName, maType,vLanList,5,false);
    if (retVal != -2)
    {
        DO_LOG_DEBUG(log_handle, "maCreate should have returned -2 (invalid tag type) but the return value was %d",retVal);
        return false;
    }

    // Try to create a new Y1731 MEG
    retVal = maCreate(mdIndex,maIndex, maName, maType,vLanList,CTAG_TYPE,true);
    if (retVal != -3)
    {
        DO_LOG_DEBUG(log_handle, "maCreate should have returned -3 (invalid MD type) but the return value was %d",retVal);
        return false;
    }

    // Try to create a MA invalid Vlan
    vLanList[0] = 7000;
    sprintf(maName, "MA_L1_%lu",maIndex);
    retVal = maCreate(mdIndex,maIndex, maName, maType,vLanList,CTAG_TYPE,true);
    if (retVal != 5)
    {
        DO_LOG_DEBUG(log_handle, "maCreate should have returned 5 (invalid Vlan) but the return value was %d",retVal);
        return false;
    }

    // Try to create a valid MA with Ctag on vlan 100
    maType = ma_characterString;
    vLanList[0] = 100;
    retVal = maCreate(mdIndex,maIndex, maName, maType,vLanList,CTAG_TYPE,false);
    if (retVal != 9)
    {
        DO_LOG_DEBUG(log_handle, "maCreate failed to create a MA when expected to succeed. Return value was %d",retVal);
        return false;
    }

    // Use Illegal MD Index
    retVal = maRead(0,0, NULL,NULL,NULL,NULL,NULL,NULL);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "maRead should have returned 1 (Unknown MA Index) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal MA Index
    retVal = maRead(mdIndex,0, NULL,NULL,NULL,NULL,NULL,NULL);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "maRead should have returned 1 (Unknown MA Index) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal MA Index
    retVal = maRead(mdIndex,maIndex+1, NULL,NULL,NULL,NULL,NULL,NULL);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "maRead should have returned 1 (Unknown MA Index) but the return value was %d",retVal);
        return false;
    }

    // Use NULL parameters
    retVal = maRead(mdIndex,maIndex, NULL,NULL,NULL,NULL,NULL,NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "mdRead should have returned 2 but the return value was %d",retVal);
        return false;
    }

    // Read and verify all parameters
    retVal = maRead(mdIndex,maIndex, &maNetInfo, &maCompInfo, &maMEFInfo, vLanList, mepIdList, &faultAlarmNetAddr);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "mdRead should have returned 2 but the return value was %d",retVal);
        return false;
    }

    if (maNetInfo.ccmInterval != ccmInterval1s)
    {
        DO_LOG_DEBUG(log_handle, "maNetInfo.ccmInterval should have returned %d but the return value was %d",ccmInterval1s,maNetInfo.ccmInterval);
        return false;
    }
    if (maNetInfo.type != maType)
    {
        DO_LOG_DEBUG(log_handle, "maNetInfo.type should have returned %d but the return value was %d",maType,maNetInfo.type);
        return false;
    }
    if (strcmp(maNetInfo.name,maName) != 0)
    {
        DO_LOG_DEBUG(log_handle, "maRead gave MA Name as '%s' but expected '%s'",maNetInfo.name, maName);
        return false;
    }
    if (maCompInfo.tagType != CTAG_TYPE)
    {
        DO_LOG_DEBUG(log_handle, "maCompInfo.tagType should have returned %d but the return value was %d",CTAG_TYPE,maNetInfo.type);
        return false;
    }
    if (maCompInfo.numVids != 1)
    {
        DO_LOG_DEBUG(log_handle, "maCompInfo.numVids should have returned 1 but the return value was %d",maCompInfo.numVids);
        return false;
    }
    if (maCompInfo.mhfCreation != ma_defMHFdefer)
    {
        DO_LOG_DEBUG(log_handle, "maCompInfo.mhfCreation should have returned %d but the return value was %d",ma_defMHFdefer,maCompInfo.mhfCreation);
        return false;
    }
    if (maCompInfo.mhfIdPermission != ma_sendIdDefer)
    {
        DO_LOG_DEBUG(log_handle, "maCompInfo.mhfIdPermission should have returned %d but the return value was %d",ma_sendIdDefer,maCompInfo.mhfIdPermission);
        return false;
    }
    if (maCompInfo.primarySelectorIdOrNone != vLanList[0])
    {
        DO_LOG_DEBUG(log_handle, "maCompInfo.primarySelectorIdOrNone should have returned %d but the return value was %d",vLanList[0],maCompInfo.primarySelectorIdOrNone);
        return false;
    }
    if (maCompInfo.primarySelectorType != ss_vlanId)
    {
        DO_LOG_DEBUG(log_handle, "maCompInfo.primarySelectorType should have returned %d but the return value was %d",ss_vlanId,maCompInfo.primarySelectorType);
        return false;
    }
    if ((vLanList[0] != 100) || (vLanList[1] != 0))
    {
        DO_LOG_DEBUG(log_handle, "vLanList[0] should be 100 but returned %d. vLanList[1] should be 0 but returned %d",vLanList[0],vLanList[1]);
        return false;
    }
    if (mepIdList[0] != 0)
    {
        DO_LOG_DEBUG(log_handle, "mepIdList[0] should be 0 but returned %d.",mepIdList[0]);
        return false;
    }
    if (faultAlarmNetAddr != 0)
    {
        DO_LOG_DEBUG(log_handle, "faultAlarmNetAddr should be 0 but returned %lu.",faultAlarmNetAddr);
        return false;
    }

    if ((maMEFInfo.maMEFCompInfo.interfaceStatusTlvIncluded != false) ||
            (maMEFInfo.maMEFCompInfo.portStatusTlvIncluded != false) ||
            (maMEFInfo.maMEFCompInfo.peerMepInfoAgingTime != 0))
    {
        DO_LOG_DEBUG(log_handle, "PS or IS values are not false OR Aging time is not 0");
        return false;
    }

    if (maMEFInfo.maMEFNetInfo.y1731Compliant != false)
    {
        DO_LOG_DEBUG(log_handle, "y1731Compliant value is not 'false'");
        return false;
    }

    if (maMEFInfo.maMEFCompInfo.connectivityStatusInterval != 3500)
    {
        DO_LOG_DEBUG(log_handle, "MEF connectivityStatusInterval was not 3 as expected");
        return false;
    }

    ccmInterval_t		ccmInterval;
    maMhfCreation_t 	maMhfCreation;
    maMhfIdPermission_t	maMhfIdPermission;

    /*
	maParam_maMhfCreation = 0,		// Mep Half Function creation option
	maParam_maMhfIdPermission,		// What, if anything, is to be included in the Sender ID TLV
	maParam_maCcmInterval,			// The CCM interval
	maParam_maFaultAlarmNetAddress,	// The network address to which Fault Alarms (12.14.7.7) are to be transmitted
	maParam_maMepIdListAdd,			// Add a mepID to the list of MEP IDs on this MA
	maParam_maMepIdListRemove,		// Remove a mepID from the list of MEP IDs on this MA
	maParam_maMEFPortStatusTlvEnable,// Enable or disable the sending of port Status TLV on CCM
	maParam_maMEFInterfaceStatusTlvEnable//
     */
    // Use invalid MA Index
    retVal = maWrite(mdIndex,0,maParam_maCcmInterval,0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 1 was expected",retVal);
        return false;
    }
    // Use invalid parameter ID
    retVal = maWrite(mdIndex,maIndex,12,&ccmInterval);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 2 was expected",retVal);
        return false;
    }

    // Use NULL parameter value pointer
    retVal = maWrite(mdIndex,maIndex,maParam_maCcmInterval,NULL);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 3 was expected",retVal);
        return false;
    }

    // Use invalid parameter value
    ccmInterval = ccmIntervalInvalid;
    retVal = maWrite(mdIndex,maIndex,maParam_maCcmInterval,&ccmInterval);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 3 was expected",retVal);
        return false;
    }

    // Use invalid parameter value
    ccmInterval = ccmInterval10min;
    retVal = maWrite(mdIndex,maIndex,maParam_maCcmInterval,&ccmInterval);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 3 was expected",retVal);
        return false;
    }

    // Set the CCM Interval to 3.3ms
    ccmInterval = ccmInterval300Hz;
    retVal = maWrite(mdIndex,maIndex,maParam_maCcmInterval,&ccmInterval);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    // Use invalid parameter value
    maMhfCreation = 0;
    retVal = maWrite(mdIndex,maIndex,maParam_maMhfCreation,&maMhfCreation);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 3 was expected",retVal);
        return false;
    }

    // Use invalid parameter value
    maMhfCreation = 10;
    retVal = maWrite(mdIndex,maIndex,maParam_maMhfCreation,&maMhfCreation);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 3 was expected",retVal);
        return false;
    }

    // Set the MhfCreation to ma_defMHFnone
    maMhfCreation = ma_defMHFnone;
    retVal = maWrite(mdIndex,maIndex,maParam_maMhfCreation,&maMhfCreation);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    // Use invalid parameter value
    maMhfIdPermission = 0;
    retVal = maWrite(mdIndex,maIndex,maParam_maMhfIdPermission,&maMhfIdPermission);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 3 was expected",retVal);
        return false;
    }

    // Use invalid parameter value
    maMhfIdPermission = 10;
    retVal = maWrite(mdIndex,maIndex,maParam_maMhfIdPermission,&maMhfIdPermission);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 3 was expected",retVal);
        return false;
    }

    // Set the MhfIdPermission to ma_sendIdNone
    maMhfIdPermission = ma_sendIdNone;
    retVal = maWrite(mdIndex,maIndex,maParam_maMhfIdPermission,&maMhfIdPermission);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    faultAlarmNetAddr = 0x11223344;
    retVal = maWrite(mdIndex,maIndex,maParam_maFaultAlarmNetAddress,&faultAlarmNetAddr);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    bool enPsTlv = true;
    bool enIsTlv = true;

    retVal = maWrite(mdIndex,maIndex,maParam_maMEFPortStatusTlvEnable,&enPsTlv);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    retVal = maWrite(mdIndex,maIndex,maParam_maMEFInterfaceStatusTlvEnable,&enIsTlv);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    mepId_t	newMepId = 1;
    retVal = maWrite(mdIndex,maIndex,maParam_maMepIdListAdd,&newMepId);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }
    newMepId = 3;
    retVal = maWrite(mdIndex,maIndex,maParam_maMepIdListAdd,&newMepId);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }
    newMepId = 0;
    retVal = maWrite(mdIndex,maIndex,maParam_maMepIdListAdd,&newMepId);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 3 was expected",retVal);
        return false;
    }

    newMepId = 2;
    retVal = maWrite(mdIndex,maIndex,maParam_maMepIdListAdd,&newMepId);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    newMepId = 3;
    retVal = maWrite(mdIndex,maIndex,maParam_maMepIdListRemove,&newMepId);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    // Read and verify all parameters
    retVal = maRead(mdIndex,maIndex, &maNetInfo, &maCompInfo, &maMEFInfo, vLanList, mepIdList, &rdFaultAlarmNetAddr);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "mdRead should have returned 2 but the return value was %d",retVal);
        return false;
    }

    if ((vLanList[0] != 1) && (vLanList[1] != 2) && (vLanList[2] != 0))
    {
        DO_LOG_DEBUG(log_handle, "The Vlan list should have been [1,2,0] but was [%d,%d,%d]", vLanList[0],vLanList[1],vLanList[2]);
        return false;
    }

    if (maCompInfo.mhfCreation != maMhfCreation)
    {
        DO_LOG_DEBUG(log_handle, "maCompInfo.mhfCreation should have returned %d but the return value was %d",maMhfCreation,maCompInfo.mhfCreation);
        return false;
    }
    if (maCompInfo.mhfIdPermission != maMhfIdPermission)
    {
        DO_LOG_DEBUG(log_handle, "maCompInfo.mhfIdPermission should have returned %d but the return value was %d",maMhfIdPermission,maCompInfo.mhfIdPermission);
        return false;
    }
    if (faultAlarmNetAddr != rdFaultAlarmNetAddr)
    {
        DO_LOG_DEBUG(log_handle, "faultAlarmNetAddr should be %lu but returned %lu.",faultAlarmNetAddr, rdFaultAlarmNetAddr);
        return false;
    }

    if ((maMEFInfo.maMEFCompInfo.interfaceStatusTlvIncluded != true) ||
            (maMEFInfo.maMEFCompInfo.portStatusTlvIncluded != true) ||
            (maMEFInfo.maMEFCompInfo.peerMepInfoAgingTime != 0))
    {
        DO_LOG_DEBUG(log_handle, "PS or IS values are not true OR Aging time is not 0");
        return false;
    }

    if (maMEFInfo.maMEFCompInfo.connectivityStatusInterval != 14)
    {
        DO_LOG_DEBUG(log_handle, "MEF connectivityStatusInterval was not 14 as expected (%lu)",maMEFInfo.maMEFCompInfo.connectivityStatusInterval);
        return false;
    }

    if (maIsMaMibIdxValid(0,0))
    {
        DO_LOG_DEBUG(log_handle, "maIsMaMibIdxValid should have returned false");
        return false;
    }

    if (maIsMaMibIdxValid(mdIndex,0))
    {
        DO_LOG_DEBUG(log_handle, "maIsMaMibIdxValid should have returned false");
        return false;
    }

    if (!maIsMaMibIdxValid(mdIndex,maIndex))
    {
        DO_LOG_DEBUG(log_handle, "maIsMaMibIdxValid should have returned true");
        return false;
    }
    return true;
}

static bool basic_deleteMATest(void)
{
    mdIndex_t	mdIndex, prevMdIndex;
    maIndex_t	maIndex;
    int			retVal;

    // Move to the last MD in the list
    mdIndex = mdReadList(0);
    while (mdIndex != 0)
    {
        prevMdIndex = mdIndex;
        mdIndex = mdReadList(mdIndex);
    }
    mdIndex = prevMdIndex;

    // Read the MA list to confirm there is a new entry at the correct index
    maIndex = maReadList(mdIndex,0);
    if (maIndex == 0)
    {
        DO_LOG_DEBUG(log_handle, "maReadList returned 0 but a non zero value was expected");
        return false;
    }

    // test to see if the MA index is valid (test validation function)
    if (maIsMaMibIdxValid(mdIndex, maIndex) == false)
    {
        DO_LOG_DEBUG(log_handle, "maIsMaMibIdxValid returned false but a value of true was expected");
        return false;
    }

    // Use Illegal MD Index
    retVal = maDelete(0,0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "maDelete should have returned 1 (invalid MA index) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal MA Index
    retVal = maDelete(mdIndex,0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "maDelete should have returned 1 (invalid MA index) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal MA Index
    retVal = maDelete(mdIndex,1000);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "maDelete should have returned 1 (invalid MA index) but the return value was %d",retVal);
        return false;
    }

    retVal = maDelete(mdIndex,maIndex);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "maDelete should have returned 2 (operation accepted) but the return value was %d",retVal);
        return false;
    }

    return true;
}

static bool basic_createMepTest(bool recursiveCall)
{
    mdIndex_t           mdIndex;
    mdIndex_t           prevMdIndex;
    maIndex_t           maIndex;
    maIndex_t           prevMaIndex;
    mepId_t             lMepId;
    mepId_t             rMepId;
    int                 retVal;
    mdMibInfo_t         mdMibInfo;
    maNetInfo_t         maNetInfo;
    mepId_t             mepIdList[5];
    uint16_t            vLanList[5] = {0,0,0,0,0};
    log_handle = 2;

    /*
       # Command 4: Set SFP 1 config values
       array set demoValues::config [list system1:mdName Microsemi system1:mdLevel 4 system1:maName demo \
       system1:vid 4000 system1:tag S-Tag system1:lMepId 11 system1:port eth0 system1:rMepId 12]

       # Command 4: Set SFP 2 config values
       array set demoValues::config [list system2:mdName Microsemi system2:mdLevel 4 system2:maName demo \
       system2:vid 4000 system2:tag S-Tag system2:lMepId 12 system2:port eth0 system2:rMepId 11]
   */

    // 1. CREATE NEW MAINTENANCE DOMAIN - Microchip, Level 4

    mdIndex = mdListReadNextMdIndex();
    retVal = mdCreate(mdIndex,"Microchip", md_characterString, 4);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "mdCreate failed to create a MD when expected to succeed. Return value was %d",retVal);
        return false;
    }
    else
    {
#ifdef DEBUG_PRINT_L1_1
        DO_LOG_DEBUG(log_handle, "mdCreate: Successfully created a MD - Microsemi, Level 4");
#endif
    }

    // 2. CREATE NEW MAINTENANCE ASSOCIATION - demo, VLAN 4000, S-TAG

    mdRead(mdIndex, &mdMibInfo, NULL);
    maIndex = mdMibInfo.maNextMibIdx;
    vLanList[0] = 4000;
    retVal = maCreate(mdIndex, maIndex, "demo", ma_characterString, vLanList,STAG_TYPE,false);
    if (retVal != 9)
    {
        DO_LOG_DEBUG(log_handle, "maCreate failed to create a MA when expected to succeed. Return value was %d",retVal);
        return false;
    }
    else
    {
#ifdef DEBUG_PRINT_L1_1
        DO_LOG_DEBUG(log_handle, "maCreate: Successfully created a MA - demo, VLAN 4000, S-TAG");
#endif
    }

    // 3. CREATE TWO MEPs - ONE LOCAL (12), ONE REMOTE (11)

    mepId_t         newMepId;

    maRead(mdIndex, maIndex, &maNetInfo, NULL, NULL, NULL, mepIdList, NULL);

    newMepId = 11;  // REMOTE MEP ID
    retVal = maWrite(mdIndex,maIndex,maParam_maMepIdListAdd,&newMepId);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }
    else
    {
#ifdef DEBUG_PRINT_L1_1
         DO_LOG_DEBUG(log_handle, "Successfully added newMepId (11) to the MA - demo");
#endif
    }

    newMepId = 12;  // LOCAL MEP ID
    retVal = maWrite(mdIndex,maIndex,maParam_maMepIdListAdd,&newMepId);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "maWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }
    else
    {
#ifdef DEBUG_PRINT_L1_1
        DO_LOG_DEBUG(log_handle, "Successfully added newMepId (12) to the MA - demo");
#endif
    }

    // CREATE LOCAL MEP FOR ID 12, Direction down, wanPort (0)
    lMepId = 12;
    retVal = lMepCreate(mdIndex, maIndex, lMepId, down, wanPort);
    //retVal = lMepCreate(mdIndex, maIndex, lMepId, down, lanPort);
    if (retVal != 9)
    {
        // DO_LOG_DEBUG(log_handle, "lMepCreate returned a value if %d when 9 was expected", retVal);
        ts_printf("lMepCreate returned a value of %d when 9 was expected", retVal);
        return false;
    }
    else
    {
#ifdef DEBUG_PRINT_L1_1
        DO_LOG_DEBUG(log_handle, ">> Created a local MEP for ID 12, direction down, wanPort (0)");
#endif
    }

    // ENABLE CCM
    osSleepMS(100); // allow settings to propagate before enabling
    bool cciEn = true;
    mepWrParam_t mepParam = mepParam_mepCciEnable;
#ifdef DEBUG_PRINT_L2
    ts_printf("mepParam_mepCciEnable\n\r");
#endif
    retVal = lMepWrite(mdIndex,maIndex, lMepId, mepParam, &cciEn);
    if (retVal != 4)
    {
        ts_printf("lMepWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    // ADMIN STATE OF MEP IS TRUE
    osSleepMS(100); // allow settings to propagate before enabling
    bool mepActive = true;
    mepParam = mepParam_mepActive;
#ifdef DEBUG_PRINT_L2
    ts_printf("mepParam_mepActive\n\r");
#endif
    retVal = lMepWrite(mdIndex,maIndex, lMepId, mepParam, &mepActive);

    if (retVal != 4)
    {
        ts_printf("lMepWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    // Enable PKT, RDI & CONN Interrupt
    mrHalRegWrite(INT_MASK_REG_ADDR, SYS_CAPT_PKT_INT_MASK | CAPT_PKT_INT_MASK | RDI_CNG_INT_MASK | CONN_INT_MASK);

    // ENABLE REMOTE MEP
/*    mepParam = mepParam_mepActiveRMepListAdd;
    rMepId = rMepReadList(mdIndex,maIndex, lMepId, 0); // get the first remote MEP on the list
    retVal = lMepWrite(mdIndex,maIndex, lMepId, mepParam, &rMepId);
    if (retVal != 4)
    {
        ts_printf("lMepWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }


    // MISCELLANEOUS OTHER PARAMETERS (NOT RELEVANT)
    mepParam = mepParam_mepFngAlarmTime;
    uint16_t        alarmTime = 500;
    retVal = lMepWrite(mdIndex,maIndex, lMepId, mepParam, &alarmTime);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "lMepWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }


    mepParam = mepParam_mepFngResetTime;
    alarmTime = 800;
    retVal = lMepWrite(mdIndex,maIndex, lMepId, mepParam, &alarmTime);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "lMepWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }


    mepParam = mepParam_mepCcmLtmPriority;
    prio_t      ccmLtmPrio = 5;
    retVal = lMepWrite(mdIndex,maIndex, lMepId, mepParam, &ccmLtmPrio);
    if (retVal != 4)
    {
        ts_printf("lMepWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }

    lowPrDef_t lowPrDef;
    lowPrDef = macRemErrXcon;
    mepParam = mepParam_mepLowPrDef;
    ts_printf("Use good value5\n\r");
    retVal = lMepWrite(mdIndex,maIndex, lMepId, mepParam, &lowPrDef);
    if (retVal != 4)
    {
        ts_printf("lMepWrite returned %d but a value of 4 was expected",retVal);
        return false;
    }
*/
    return true;
}

static bool basic_deleteMepTest(void)
{
    mdIndex_t	mdIndex, prevMdIndex;
    maIndex_t	maIndex, prevMaIndex;
    mepId_t		lMepId;
    int			retVal;

    // Move to the last MD in the list
    mdIndex = mdReadList(0);
    while (mdIndex != 0)
    {
        prevMdIndex = mdIndex;
        mdIndex = mdReadList(mdIndex);
    }
    mdIndex = prevMdIndex;

    // Move to the last MA in the list
    maIndex = maReadList(mdIndex, 0);
    while (maIndex != 0)
    {
        prevMaIndex = maIndex;
        maIndex = maReadList(mdIndex,maIndex);
    }
    maIndex = prevMaIndex;

    // Read the Local MEP list to confirm there is a new entry at the correct index
    lMepId = lMepReadList(mdIndex,maIndex,0);
    if (lMepId == 0)
    {
        DO_LOG_DEBUG(log_handle, "lMepReadList returned 0 but a non zero value was expected");
        return false;
    }

    // test to see if the Local MEP index is valid (test validation function)
    if (mepIsLMepIdValid(mdIndex, maIndex, lMepId) == false)
    {
        DO_LOG_DEBUG(log_handle, "mepIsLMepIdValid returned false but a value of true was expected");
        return false;
    }

    // Use Illegal MD Index
    retVal = lMepDelete(0,0,0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "lMepDelete should have returned 1 (invalid index) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal MA Index
    retVal = lMepDelete(mdIndex,0,0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "lMepDelete should have returned 1 (invalid index) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal MA Index
    retVal = lMepDelete(mdIndex,1000, 0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "lMepDelete should have returned 1 (invalid index) but the return value was %d",retVal);
        return false;
    }

    // Use Illegal Local MEP Index
    retVal = lMepDelete(mdIndex, maIndex, 0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "lMepDelete should have returned 1 (invalid index) but the return value was %d",retVal);
        return false;
    }

    retVal = lMepDelete(mdIndex,maIndex,lMepId);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "lMepDelete should have returned 2 (operation accepted) but the return value was %d",retVal);
        return false;
    }

    return true;
}

static void printMepLbInfo(mepLbInfo_t mepLbInfo)
{
    printf("----------------------- mepLbInfo --------------\n");
    printf("lbrInBadMsdu        = %lu\n", mepLbInfo.__lbrInBadMsdu);
    printf("_lbrIn              = %lu\n", mepLbInfo._lbrIn);
    printf("_lbrInOutOfOrder    = %lu\n", mepLbInfo._lbrInOutOfOrder);
    printf("_lbrOut             = %lu\n", mepLbInfo._lbrOut);
    printf("_txLbmDataTlv       = %x,%x,%x,%x,...\n", mepLbInfo._txLbmDataTlv[0],mepLbInfo._txLbmDataTlv[1],mepLbInfo._txLbmDataTlv[2],mepLbInfo._txLbmDataTlv[3]);
    printf("_txLbmDataTlvLength = %d\n", mepLbInfo._txLbmDataTlvLength);
    printf("txLbmSeqNumber      = %lu\n", mepLbInfo.txLbmSeqNumber);
    printf("nextLbmTransId      = %lu\n", mepLbInfo.nextLbmTransId);
    printf("txLbmDestMepId      = %d\n", mepLbInfo.txLbmDestMepId);
    printf("txLbmDestIsMepId    = %s\n", mepLbInfo.txLbmDestIsMepId ? "True" : "False");
    printf("txLbmDestMacAddr    = %x.%x.%x.%x.%x.%x\n", mepLbInfo.txLbmDestMacAddr[0],mepLbInfo.txLbmDestMacAddr[1], mepLbInfo.txLbmDestMacAddr[2],mepLbInfo.txLbmDestMacAddr[3], mepLbInfo.txLbmDestMacAddr[4],mepLbInfo.txLbmDestMacAddr[5]);
    printf("txLbmNumMessages    = %d\n", mepLbInfo.txLbmNumMessages);
    printf("txLbmVlanPriority   = %d\n", mepLbInfo.txLbmVlanPriority);
    printf("txLbmVlanDropEnable = %s\n", mepLbInfo.txLbmVlanDropEnable ? "DROP" : "NO DROP");
    printf("txLbmStatus         = %s\n", mepLbInfo.txLbmStatus ? "GOOD" : "BAD");
    printf("txLbmResultOk       = %s\n", mepLbInfo.txLbmResultOk ? "YES" : "NO");
    printf("----------------------------------------\n");
}

static void printMepLbMEFInfo(mepLbMefInfo_t mepLbMefInfo)
{
    printf("----------------------- mepLbMefInfo --------------\n");
    printf("_dataPattern        = %d\n", mepLbMefInfo._dataPattern);
    printf("_numLbrInCrcError   = %lu\n", mepLbMefInfo._numLbrInCrcError);
    printf("_testTlvIncluded    = %s\n", mepLbMefInfo._testTlvIncluded ? "True" : "False");
    printf("_testTlvPattern     = %d\n", mepLbMefInfo._testTlvPattern);
    printf("frameSize           = %d\n", mepLbMefInfo.frameSize);
    printf("interval            = %dms\n", mepLbMefInfo.interval);
    printf("multicastEnable     = %s\n", mepLbMefInfo.multicastEnable ? "Yes" : "No");
    printf("timeout             = %dms\n", mepLbMefInfo.timeout);
    printf("----------------------------------------\n");

}

static bool basicLbTest(void)
{
    mdIndex_t	mdIndex, prevMdIndex;
    maIndex_t	maIndex, prevMaIndex;
    mepId_t		lMepId, prevLMepId;
    int			retVal;

    // Move to the last MD in the list
    mdIndex = mdReadList(0);
    while (mdIndex != 0)
    {
        prevMdIndex = mdIndex;
        mdIndex = mdReadList(mdIndex);
    }
    mdIndex = prevMdIndex;

    // Move to the last MA in the list
    maIndex = maReadList(mdIndex, 0);
    while (maIndex != 0)
    {
        prevMaIndex = maIndex;
        maIndex = maReadList(mdIndex,maIndex);
    }
    maIndex = prevMaIndex;

    // Read the Local MEP list to confirm there is a new entry at the correct index
    lMepId = lMepReadList(mdIndex,maIndex,0);
    while (lMepId != 0)
    {
        prevLMepId = lMepId;
        lMepId = maReadList(mdIndex,lMepId);
    }
    lMepId = prevLMepId;

    if (lMepId == 0 || maIndex == 0 || mdIndex == 0)
    {
        DO_LOG_DEBUG(log_handle, "lMepReadList returned 0 but a non zero value was expected");
        return false;
    }

    mepLbTxInfo_t 		mepLbTxInfo;
    mepLbMefTxInfo_t	mepLbMefTxInfo;

    // Set some default values...
    mepLbTxInfo.txLbmVlanDropEnable = false;
    mepLbTxInfo.txLbmDestIsMepId = true;
    mepLbTxInfo.txLbmDestMepId = rMepReadList(mdIndex,maIndex,lMepId,0);
    if (mepLbTxInfo.txLbmDestMepId == 0)
    {
        DO_LOG_DEBUG(log_handle, "rMepReadList returned 0 but a non zero value was expected");
        return false;
    }

    // Use a wrong index
    retVal = lbTransmit(0, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 1 was expected", retVal);
        return false;
    }
    // Use a wrong index
    retVal = lbTransmit(mdIndex, maIndex, 0, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 1 was expected", retVal);
        return false;
    }

    // Use incorrect values
    mepLbTxInfo.txLbmNumMessages = 0;
    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 2 was expected", retVal);
        return false;
    }

    // Use incorrect values
    mepLbTxInfo.txLbmNumMessages = MAX_LB_NUM_BURSTS + 1;
    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 2 was expected", retVal);
        return false;
    }

    // Use incorrect values
    mepLbTxInfo.txLbmNumMessages = 10;
    mepLbTxInfo._txLbmDataTlvLength = MAX_LB_DATA_TLV + 1;
    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 3 was expected", retVal);
        return false;
    }

    // Use incorrect values
    mepLbTxInfo._txLbmDataTlvLength = 100;
    mepLbTxInfo.txLbmVlanPriority = 9;
    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 4 was expected", retVal);
        return false;
    }

    // Use incorrect values
    mepLbTxInfo.txLbmVlanPriority = prio3;
    mepLbTxInfo._txLbmDataTlvLength = 0;		// setting this to 0 means use the MEF parameters
    mepLbMefTxInfo.frameSize = MAX_LBM_PKT_SIZE + 1;
    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 3 was expected", retVal);
        return false;
    }

    // Use incorrect values
    mepLbTxInfo.txLbmVlanPriority = prio3;
    mepLbTxInfo._txLbmDataTlvLength = 0;		// setting this to 0 means use the MEF parameters
    mepLbMefTxInfo.frameSize = 100;
    mepLbMefTxInfo.interval = 0xFFFF;
    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != -1)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if -1 was expected", retVal);
        return false;
    }

    mepLbInfo_t		mepLbInfo;
    mepLbMefInfo_t	mepLbMefInfo;

    retVal = lMepRead(mdIndex,maIndex,lMepId,
            NULL,
            NULL,
            &mepLbInfo,
            &mepLbMefInfo,
            NULL,
            //TODO: add: mepLtInfo_t		*mepLtInfo,
            NULL,
            NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "lMepRead returned %d but a value if 2 was expected", retVal);
        return false;
    }

    printMepLbInfo(mepLbInfo);
    printMepLbMEFInfo(mepLbMefInfo);
    uint8_t	k;
    //uint32_t	delay;
    //uint8_t		resend = 1;

    //bool 	mepCciEnable = false;

    // Must wait for a few seconds to allow CCMs to establish and SA to be learned
    osSleepMS(4000);

    // Use GOOD IEEE values
    mepLbTxInfo._txLbmDataTlvLength = 50;		// setting this to non zero means use the IEEE parameters
    mepLbMefTxInfo.interval = 1000;

    //SEND_10_CFM_LBM:
    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, NULL);
    if (retVal != 6)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 6 was expected", retVal);
        return false;
    }

    mepLbAdvanceStats_t mepLbAdvanceStats;

    retVal = lbReadAdvancedStats(mdIndex, maIndex, lMepId, &mepLbAdvanceStats);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "lbReadAdvancedStats returned %d but a value if 2 was expected", retVal);
        return false;
    }

    //osSleepMS(1000);
    k = 11;
    while(k-- != 0)
    {
        retVal = lMepRead(mdIndex,maIndex,lMepId,
                NULL,
                NULL,
                &mepLbInfo,
                &mepLbMefInfo,
                NULL,
                //TODO: add: mepLtInfo_t		*mepLtInfo,
                NULL,
                NULL);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "lMepRead returned %d but a value if 2 was expected", retVal);
            return false;
        }

        retVal = lbReadAdvancedStats(mdIndex, maIndex, lMepId, &mepLbAdvanceStats);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "lbReadAdvancedStats returned %d but a value if 6 was expected", retVal);
            return false;
        }

        //printMepLbInfo(mepLbInfo);
        //printMepLbMEFInfo(mepLbMefInfo);
        printf("Tx pkts = %lu\n", mepLbAdvanceStats.numTxPkts);
        osSleepMS(1000);
        //delay = 0x3FFFF;
        //while (delay-- !=0 );
    }
    printf("** Rx pkts = %lu\n", mepLbAdvanceStats.numRxPkts);
    printMepLbInfo(mepLbInfo);
    retVal = lbReadAdvancedStats(mdIndex, maIndex, lMepId, &mepLbAdvanceStats);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "lbReadAdvancedStats returned %d but a value if 2 was expected", retVal);
        return false;
    }

    if (mepLbAdvanceStats.numTxPkts != mepLbTxInfo.txLbmNumMessages)
    {
        DO_LOG_DEBUG(log_handle, "Loopback send %lu packets but was requested to send %lu packets", mepLbAdvanceStats.numTxPkts, mepLbTxInfo.txLbmNumMessages);
        return false;
    }

    //if (resend-- > 0)
    //	goto SEND_10_CFM_LBM;

    // Use GOOD IEEE values
    mepLbTxInfo._txLbmDataTlvLength = 500;		// setting this to non zero means use the IEEE parameters
    mepLbTxInfo.txLbmNumMessages = 900;
    mepLbMefTxInfo.interval = 10;
    mepLbTxInfo.txLbmDestIsMepId = false;
    mepLbTxInfo.txLbmDestMacAddr[0] = 0x00;
    mepLbTxInfo.txLbmDestMacAddr[1] = 0x07;
    mepLbTxInfo.txLbmDestMacAddr[2] = 0xED;
    mepLbTxInfo.txLbmDestMacAddr[3] = 0xFF;
    mepLbTxInfo.txLbmDestMacAddr[4] = 0x67;
    mepLbTxInfo.txLbmDestMacAddr[5] = 0xC1;
    mepLbMefTxInfo.multicastEnable = false;
    mepLbMefTxInfo.timeout = 5000;

    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 6)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 6 was expected", retVal);
        return false;
    }
    k = 11;
    while(k-- != 0)
    {
        retVal = lMepRead(mdIndex,maIndex,lMepId,
                NULL,
                NULL,
                &mepLbInfo,
                &mepLbMefInfo,
                NULL,
                //TODO: add: mepLtInfo_t		*mepLtInfo,
                NULL,
                NULL);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "lMepRead returned %d but a value if 2 was expected", retVal);
            return false;
        }

        retVal = lbReadAdvancedStats(mdIndex, maIndex, lMepId, &mepLbAdvanceStats);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "lbReadAdvancedStats returned %d but a value if 6 was expected", retVal);
            return false;
        }

        //printMepLbInfo(mepLbInfo);
        //printMepLbMEFInfo(mepLbMefInfo);
        printf("Tx pkts = %lu\n", mepLbAdvanceStats.numTxPkts);
        osSleepMS(1000);
        //delay = 0x3FFFF;
        //while (delay-- !=0 );
    }
    printf("** Rx pkts = %lu\n", mepLbAdvanceStats.numRxPkts);
    printMepLbInfo(mepLbInfo);

    if (mepLbAdvanceStats.numTxPkts != mepLbTxInfo.txLbmNumMessages)
    {
        DO_LOG_DEBUG(log_handle, "Loopback send %lu packets but was requested to send %lu packets", mepLbAdvanceStats.numTxPkts, mepLbTxInfo.txLbmNumMessages);
        return false;
    }

    //---------------------------------- test Multicast loopback ------------------------
    mepLbTxInfo._txLbmDataTlvLength = 0;		// setting this to non zero means use the IEEE parameters
    mepLbTxInfo.txLbmNumMessages = 1;
    mepLbMefTxInfo._testTlvIncluded = true;
    mepLbMefTxInfo.frameSize = 100;
    mepLbMefTxInfo.interval = 1;
    mepLbMefTxInfo.multicastEnable = true;
    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 6)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 6 was expected", retVal);
        return false;
    }
    k = 2;
    while(k-- != 0)
    {
        retVal = lMepRead(mdIndex,maIndex,lMepId,
                NULL,
                NULL,
                &mepLbInfo,
                &mepLbMefInfo,
                NULL,
                //TODO: add: mepLtInfo_t		*mepLtInfo,
                NULL,
                NULL);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "lMepRead returned %d but a value if 2 was expected", retVal);
            return false;
        }

        retVal = lbReadAdvancedStats(mdIndex, maIndex, lMepId, &mepLbAdvanceStats);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "lbReadAdvancedStats returned %d but a value if 6 was expected", retVal);
            return false;
        }

        //printMepLbInfo(mepLbInfo);
        //printMepLbMEFInfo(mepLbMefInfo);
        printf("Tx pkts = %lu\n", mepLbAdvanceStats.numTxPkts);
        osSleepMS(1000);
        //delay = 0x3FFFF;
        //while (delay-- !=0 );
    }
    printf("** Rx pkts = %lu\n", mepLbAdvanceStats.numRxPkts);
    printMepLbInfo(mepLbInfo);

    if (mepLbAdvanceStats.numTxPkts != mepLbTxInfo.txLbmNumMessages)
    {
        DO_LOG_DEBUG(log_handle, "Loopback send %lu packets but was requested to send %lu packets", mepLbAdvanceStats.numTxPkts, mepLbTxInfo.txLbmNumMessages);
        return false;
    }

    macAddress_t macAddress;

    retVal = lbReadNextMcMAC(mdIndex, maIndex, lMepId, 1, 1, macAddress);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "lbReadNextMcMAC returned %d but a value if 1 was expected", retVal);
        return false;
    }
    printf("MAC #1= %X.%X.%X.%X.%X.%X\n",macAddress[0],macAddress[1],macAddress[2],macAddress[3],macAddress[4],macAddress[5]);
    retVal = lbReadNextMcMAC(mdIndex, maIndex, lMepId, 1, 2, macAddress);
    if (retVal != 0)
    {
        DO_LOG_DEBUG(log_handle, "lbReadNextMcMAC returned %d but a value if 0 was expected", retVal);
        return false;
    }

    //---------------------------------- test advanced loopback (Burst Mode)------------------------
    mepLbTxAdvanceCfg_t mepLbTxAdvanceCfg;
    mepLbTxAdvanceCfg.enableAdvMode = true;
    mepLbTxAdvanceCfg.lbMode = lb_burstMode;
    mepLbTxAdvanceCfg.interBurstTime = 1000000;
    mepLbTxAdvanceCfg.numberOfBursts = 4;
    mepLbTxAdvanceCfg.pktsPerBurst = 200;
    mepLbTxAdvanceCfg.txActive = true;
    mepLbTxAdvanceCfg.transmitRate = 1;
    retVal = lbTransmitAdvanced(mdIndex, maIndex, lMepId, &mepLbTxAdvanceCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmitAdvanced returned %d but a value if 4 was expected", retVal);
        return false;
    }
    mepLbTxInfo._txLbmDataTlvLength = 0;		// setting this to non zero means use the IEEE parameters
    mepLbTxInfo.txLbmNumMessages = 1;
    mepLbMefTxInfo._testTlvIncluded = true;
    mepLbMefTxInfo.frameSize = 100;
    mepLbMefTxInfo.interval = 1;
    mepLbMefTxInfo.multicastEnable = false;
    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 6)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 6 was expected", retVal);
        return false;
    }
    k = 10;
    while(k-- != 0)
    {
        retVal = lMepRead(mdIndex,maIndex,lMepId,
                NULL,
                NULL,
                &mepLbInfo,
                &mepLbMefInfo,
                NULL,
                //TODO: add: mepLtInfo_t		*mepLtInfo,
                NULL,
                NULL);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "lMepRead returned %d but a value if 2 was expected", retVal);
            return false;
        }

        retVal = lbReadAdvancedStats(mdIndex, maIndex, lMepId, &mepLbAdvanceStats);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "lbReadAdvancedStats returned %d but a value if 6 was expected", retVal);
            return false;
        }

        //printMepLbInfo(mepLbInfo);
        //printMepLbMEFInfo(mepLbMefInfo);
        printf("Tx pkts = %lu\n", mepLbAdvanceStats.numTxPkts);
        osSleepMS(1000);
        //delay = 0x3FFFF;
        //while (delay-- !=0 );
    }
    printf("** Rx pkts = %lu\n", mepLbAdvanceStats.numRxPkts);
    printMepLbInfo(mepLbInfo);

    if (mepLbAdvanceStats.numTxPkts != (mepLbTxAdvanceCfg.numberOfBursts * mepLbTxAdvanceCfg.pktsPerBurst))
    {
        DO_LOG_DEBUG(log_handle, "Loopback send %lu packets but was requested to send %lu packets", mepLbAdvanceStats.numTxPkts, (mepLbTxAdvanceCfg.numberOfBursts * mepLbTxAdvanceCfg.pktsPerBurst));
        return false;
    }

    //---------------------------------- test advanced loopback Continuous Mode ------------------------
    mepLbTxAdvanceCfg.enableAdvMode = true;
    mepLbTxAdvanceCfg.lbMode = lb_continuousMode;
    mepLbTxAdvanceCfg.interBurstTime = 1000000;
    mepLbTxAdvanceCfg.numberOfBursts = 4;
    mepLbTxAdvanceCfg.pktsPerBurst = 200;
    mepLbTxAdvanceCfg.txActive = true;
    mepLbTxAdvanceCfg.transmitRate = 1;
    retVal = lbTransmitAdvanced(mdIndex, maIndex, lMepId, &mepLbTxAdvanceCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmitAdvanced returned %d but a value if 4 was expected", retVal);
        return false;
    }
    mepLbTxInfo._txLbmDataTlvLength = 0;		// setting this to non zero means use the IEEE parameters
    mepLbTxInfo.txLbmNumMessages = 1;
    mepLbMefTxInfo._testTlvIncluded = true;
    mepLbMefTxInfo.frameSize = 100;
    mepLbMefTxInfo.interval = 1;
    mepLbMefTxInfo.multicastEnable = false;
    retVal = lbTransmit(mdIndex, maIndex, lMepId, &mepLbTxInfo, &mepLbMefTxInfo);
    if (retVal != 6)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmit returned %d but a value if 6 was expected", retVal);
        return false;
    }
    k = 10;
    while(k-- != 0)
    {
        retVal = lMepRead(mdIndex,maIndex,lMepId,
                NULL,
                NULL,
                &mepLbInfo,
                &mepLbMefInfo,
                NULL,
                //TODO: add: mepLtInfo_t		*mepLtInfo,
                NULL,
                NULL);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "lMepRead returned %d but a value if 2 was expected", retVal);
            return false;
        }

        retVal = lbReadAdvancedStats(mdIndex, maIndex, lMepId, &mepLbAdvanceStats);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "lbReadAdvancedStats returned %d but a value if 6 was expected", retVal);
            return false;
        }

        //printMepLbInfo(mepLbInfo);
        //printMepLbMEFInfo(mepLbMefInfo);
        printf("Tx pkts = %lu\n", mepLbAdvanceStats.numTxPkts);
        osSleepMS(1000);
        //delay = 0x3FFFF;
        //while (delay-- !=0 );
    }
    mepLbTxAdvanceCfg.txActive = false;
    retVal = lbTransmitAdvanced(mdIndex, maIndex, lMepId, &mepLbTxAdvanceCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "lbTransmitAdvanced returned %d but a value if 4 was expected", retVal);
        return false;
    }

    printf("** Rx pkts = %lu\n", mepLbAdvanceStats.numRxPkts);
    printMepLbInfo(mepLbInfo);

    if (mepLbAdvanceStats.numTxPkts == 0)
    {
        DO_LOG_DEBUG(log_handle, "Loopback send %lu packets but was requested to send one or more packets", mepLbAdvanceStats.numTxPkts);
        return false;
    }

    return(true);
}

static bool basicDmTest(void)
{
    mdIndex_t	mdIndex, prevMdIndex;
    maIndex_t	maIndex, prevMaIndex;
    mepId_t		lMepId, prevLMepId;
    pmIndex_t 	dmIndex,prevDmIndex;
    int			retVal;

    // Move to the last MD in the list
    mdIndex = mdReadList(0);
    while (mdIndex != 0)
    {
        prevMdIndex = mdIndex;
        mdIndex = mdReadList(mdIndex);
    }
    mdIndex = prevMdIndex;

    // Move to the last MA in the list
    maIndex = maReadList(mdIndex, 0);
    while (maIndex != 0)
    {
        prevMaIndex = maIndex;
        maIndex = maReadList(mdIndex,maIndex);
    }
    maIndex = prevMaIndex;

    // Read the Local MEP list to confirm there is a new entry at the correct index
    lMepId = lMepReadList(mdIndex,maIndex,0);
    while (lMepId != 0)
    {
        prevLMepId = lMepId;
        lMepId = maReadList(mdIndex,lMepId);
    }
    lMepId = prevLMepId;

    if (lMepId == 0 || maIndex == 0 || mdIndex == 0)
    {
        DO_LOG_DEBUG(log_handle, "lMepReadList returned 0 but a non zero value was expected");
        return false;
    }

    prevDmIndex = 0;
    dmIndex = delayMeasurementReadList(mdIndex, maIndex, lMepId, prevDmIndex);
    if (dmIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementReadList returned %d but was expected to return 0", dmIndex);
        return false;
    }

    dmCfg_t				dmCfg;
    dmCfgMeasBin_t		dmCfgMeasBin;
    dmThresholdCfg_t	dmThresholdCfg;
    //mepInfo_t 		mepInfo;
    //mepCcInfo_t		mepCcInfo;
    //mepLbInfo_t		mepLbInfo;
    //mepLbMefInfo_t	mepLbMefInfo;
    //mepFngInfo_t	mepFngInfo;
    //TODO: add: mepLtInfo_t		*mepLtInfo,
    mepMefInfo_t	mepMefInfo;
    //macAddress_t	macAddress;

    // Try to read back the MEP info... use an illegal Index
    retVal = lMepRead(mdIndex,maIndex,lMepId,
            NULL,
            NULL,
            NULL,
            NULL,
            NULL,
            //TODO: add: mepLtInfo_t		*mepLtInfo,
            &mepMefInfo,
            NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "lMepRead returned %d but a value of 2 was expected",retVal);
        return false;
    }

    pmSetDmCfgDefaults(&dmCfg);
    pmSetDmDefaultBins(dmCfgMeasBin);
    pmSetDmThresholdDefaults(&dmThresholdCfg);

    dmCfg.cfg.destIsMepId = true;
    dmCfg.cfg.destMepId = rMepReadList(mdIndex,maIndex,lMepId,0);;
    dmIndex = mepMefInfo.operNextIndex;
    //  Use bad index
    retVal = delayMeasurementCreate(mdIndex, maIndex, 0, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 1", retVal);
        return false;
    }

    //  Use bad index
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, 0, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 1", retVal);
        return false;
    }

    //  Use bad type
    dmCfg.type = dm1DmTx;
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad data pattern
    dmCfg.type = dmDmm;
    dmCfg.cfg.dataPattern = onesPattern;
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad frame size
    dmCfg.cfg.dataPattern = zeroPattern;
    dmCfg.cfg.frameSize = 63;
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad measurementEnable mask
    dmCfg.cfg.frameSize = 64;
    dmCfg.cfg.measurementEnable = ~dmCfg.cfg.measurementEnable;
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad measurementEnable mask
    dmCfg.cfg.frameSize = 64;
    dmCfg.cfg.measurementEnable = 0x03C0003F;;
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad messagePeriod
    dmCfg.cfg.measurementEnable = 0x03C0003E;
    dmCfg.cfg.messagePeriod = 101;
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad startTimeType
    dmCfg.cfg.messagePeriod = 100;
    dmCfg.cfg.startTimeType = fixed;
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad stopTimeType
    dmCfg.cfg.startTimeType = immediate;
    dmCfg.cfg.stopTimeType = relative;
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad testTlvIncluded value
    dmCfg.cfg.stopTimeType = none;
    dmCfg.cfg.testTlvIncluded = true;
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use GOOD values ***
    dmCfg.cfg.testTlvIncluded = false;
    dmCfg.cfg.measurementInterval = 1;	// 1 minute
    retVal = delayMeasurementCreate(mdIndex, maIndex, lMepId, dmIndex, &dmCfg, &dmThresholdCfg, dmCfgMeasBin);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementCreate returned %d but was expected to return 4", retVal);
        return false;
    }

    dmMeasuredStats_t	measuredStats;
    dmStats_t			currentStats;
    dmStatsBins_t		currenStatsBins;

    osSleepMS(5000);
    retVal = delayMeasurementRead(mdIndex, maIndex, lMepId, dmIndex,
            &dmCfg,
            &measuredStats,
            &currentStats,
            currenStatsBins,
            &dmThresholdCfg,
            dmCfgMeasBin);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "delayMeasurementRead returned %d but was expected to return 2", retVal);
        return false;
    }

    printf("2 way delay = %luus; 2 way variation = %luus\n",measuredStats.frameDelayTwoWay, measuredStats.ifdvTwoWay);
    printf("Num Tx = %lu\nNum Rx = %lu\n", currentStats.soamPdusSent, currentStats.soamPdusReceived);
    printf("Elapsed time = %lu Sec\n", currentStats.elapsedTime/100);
    return true;
}


static bool basicLmTest(void)
{
    mdIndex_t	mdIndex, prevMdIndex;
    maIndex_t	maIndex, prevMaIndex;
    mepId_t		lMepId, prevLMepId;
    pmIndex_t 	lmIndex,prevLmIndex;
    int			retVal;

    // Move to the last MD in the list
    mdIndex = mdReadList(0);
    while (mdIndex != 0)
    {
        prevMdIndex = mdIndex;
        mdIndex = mdReadList(mdIndex);
    }
    mdIndex = prevMdIndex;

    // Move to the last MA in the list
    maIndex = maReadList(mdIndex, 0);
    while (maIndex != 0)
    {
        prevMaIndex = maIndex;
        maIndex = maReadList(mdIndex,maIndex);
    }
    maIndex = prevMaIndex;

    // Read the Local MEP list to confirm there is a new entry at the correct index
    lMepId = lMepReadList(mdIndex,maIndex,0);
    while (lMepId != 0)
    {
        prevLMepId = lMepId;
        lMepId = maReadList(mdIndex,lMepId);
    }
    lMepId = prevLMepId;

    if (lMepId == 0 || maIndex == 0 || mdIndex == 0)
    {
        DO_LOG_DEBUG(log_handle, "lMepReadList returned 0 but a non zero value was expected");
        return false;
    }

    prevLmIndex = 0;
    lmIndex = lossMeasurementReadList(mdIndex, maIndex, lMepId, prevLmIndex);
    if (lmIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementReadList returned %d but was expected to return 0", lmIndex);
        return false;
    }

    lmCfg_t				lmCfg;
    lmThresholdCfg_t	lmThresholdCfg;
    //mepInfo_t 		mepInfo;
    //mepCcInfo_t		mepCcInfo;
    //mepLbInfo_t		mepLbInfo;
    //mepLbMefInfo_t	mepLbMefInfo;
    //mepFngInfo_t	mepFngInfo;
    //TODO: add: mepLtInfo_t		*mepLtInfo,
    mepMefInfo_t	mepMefInfo;
    //macAddress_t	macAddress;

    // Try to read back the MEP info... use an illegal Index
    retVal = lMepRead(mdIndex,maIndex,lMepId,
            NULL,
            NULL,
            NULL,
            NULL,
            NULL,
            //TODO: add: mepLtInfo_t		*mepLtInfo,
            &mepMefInfo,
            NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "lMepRead returned %d but a value of 2 was expected",retVal);
        return false;
    }

    pmSetLmCfgDefaults(&lmCfg);
    pmSetLmThresholdDefaults(&lmThresholdCfg);

    lmCfg.cfg.destIsMepId = true;
    lmCfg.cfg.destMepId = rMepReadList(mdIndex,maIndex,lMepId,0);;
    lmIndex = mepMefInfo.operNextIndex;
    //  Use bad index
    retVal = lossMeasurementCreate(mdIndex, maIndex, 0, lmIndex, &lmCfg, &lmThresholdCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 1", retVal);
        return false;
    }

    //  Use bad index
    retVal = lossMeasurementCreate(mdIndex, maIndex, lMepId, 0, &lmCfg, &lmThresholdCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 1", retVal);
        return false;
    }

    //  Use bad type
    lmCfg.type = lmLmm;
    retVal = lossMeasurementCreate(mdIndex, maIndex, lMepId, lmIndex, &lmCfg, &lmThresholdCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad data pattern
    lmCfg.type = lmSlm;
    lmCfg.cfg.dataPattern = onesPattern;
    retVal = lossMeasurementCreate(mdIndex, maIndex, lMepId, lmIndex, &lmCfg, &lmThresholdCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad frame size
    lmCfg.cfg.dataPattern = zeroPattern;
    lmCfg.cfg.frameSize = 63;
    retVal = lossMeasurementCreate(mdIndex, maIndex, lMepId, lmIndex, &lmCfg, &lmThresholdCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad measurementEnable mask
    lmCfg.cfg.frameSize = 64;
    lmCfg.cfg.measurementEnable = ~lmCfg.cfg.measurementEnable;
    retVal = lossMeasurementCreate(mdIndex, maIndex, lMepId, lmIndex, &lmCfg, &lmThresholdCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad messagePeriod
    lmCfg.cfg.measurementEnable = ~lmCfg.cfg.measurementEnable;
    lmCfg.cfg.messagePeriod = 101;
    retVal = lossMeasurementCreate(mdIndex, maIndex, lMepId, lmIndex, &lmCfg, &lmThresholdCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad startTimeType
    lmCfg.cfg.messagePeriod = 100;
    lmCfg.cfg.startTimeType = fixed;
    retVal = lossMeasurementCreate(mdIndex, maIndex, lMepId, lmIndex, &lmCfg, &lmThresholdCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad stopTimeType
    lmCfg.cfg.startTimeType = immediate;
    lmCfg.cfg.stopTimeType = relative;
    retVal = lossMeasurementCreate(mdIndex, maIndex, lMepId, lmIndex, &lmCfg, &lmThresholdCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use bad testTlvIncluded value
    lmCfg.cfg.stopTimeType = none;
    lmCfg.cfg.testTlvIncluded = true;
    retVal = lossMeasurementCreate(mdIndex, maIndex, lMepId, lmIndex, &lmCfg, &lmThresholdCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 3", retVal);
        return false;
    }

    //  Use GOOD values ***
    lmCfg.cfg.testTlvIncluded = false;
    lmCfg.cfg.measurementInterval = 1;	// 1 minute
    retVal = lossMeasurementCreate(mdIndex, maIndex, lMepId, lmIndex, &lmCfg, &lmThresholdCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementCreate returned %d but was expected to return 4", retVal);
        return false;
    }

    lmMeasuredStats_t	measuredStats;
    lmAvailStats_t		currentAvailStats;
    lmStats_t			currentStats;

    osSleepMS(5000);
    retVal = lossMeasurementRead(mdIndex, maIndex, lMepId, lmIndex,
            &lmCfg,
            &measuredStats,
            &currentAvailStats,
            &currentStats,
            &lmThresholdCfg);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "lossMeasurementRead returned %d but was expected to return 2", retVal);
        return false;
    }

    printf("Forward loss = %.3f%%; Backward Loss = %.3f%%\n",measuredStats.forwardFlr/1000.0, measuredStats.backwardFlr/1000.0);
    printf("Num Tx = %lu\nNum Rx = %lu\n", currentStats.soamPdusSent, currentStats.soamPdusReceived);
    printf("Elapsed time = %lu Sec\n", currentStats.elapsedTime/100);
    return true;
}

bool runCFMTests(void)
{
    bool overAllResult = true;
    log_handle = 2;
    if (!basic_createMDTest(false))
    {
        DO_LOG_DEBUG(log_handle, "Basic MD Creation - Test Failed.");

        overAllResult = false;
    }
    ts_printf("Basic MD Creation - Test ok.\n\r");
    if (!basic_deleteMDTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic MD Deletion - Test Failed.");
        ts_printf("Basic MD Deletion - Test Failed.\n\r");
        overAllResult = false;
    }

    //Create two MDs...
    if (!basic_createMDTest(true) && !basic_createMDTest(true))
    {
        DO_LOG_DEBUG(log_handle, "Create 2 basic MDs -  Test Failed.");
        overAllResult = false;
    }

    // Delete the two MDs...
    if (!basic_deleteMDTest() && !basic_deleteMDTest())
    {
        DO_LOG_DEBUG(log_handle, "Delete 2 basic MDs - Test Failed.");
        overAllResult = false;
    }

    int k;
    for (k=0;k<32;k++)
    {
        if (!basic_createMDTest(true))
        {
            DO_LOG_DEBUG(log_handle, "Basic MD Creation %d of 32 - Test Failed.",k+1);
            overAllResult = false;
        }
    }

    for (k=0;k<32;k++)
    {
        if (!basic_deleteMDTest())
        {
            DO_LOG_DEBUG(log_handle, "Basic MD Deletion %d of 32 - Test Failed.",k+1);
            overAllResult = false;
        }
    }

    if (!basic_createMATest(false))
    {
        DO_LOG_DEBUG(log_handle, "Basic MA Creation - Test Failed.");
        overAllResult = false;
    }

    if (!basic_deleteMATest())
    {
        DO_LOG_DEBUG(log_handle, "Basic MA Deletion - Test Failed.");
        overAllResult = false;
    }

    if (!basic_deleteMDTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic MD Deletion - Test Failed.");
        overAllResult = false;
    }

    if (!basic_createMATest(false))
    {
        DO_LOG_DEBUG(log_handle, "Basic MA Creation - Test Failed.");
        overAllResult = false;
    }
    if (!basic_deleteMDTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic MD Deletion - Test Failed.");
        overAllResult = false;
    }

    pVidEntry_t	pVidEntry;
    pVidEntry.vlan = 0x123;
    pVidEntry.de = 0;
    pVidEntry.prio = 4;
    writePVidTable(0, &pVidEntry);
#ifdef DEBUG_PRINT_L1
    ts_printf("Basic Local Maintenance End Point creation - In Progress ...\n\r");
#endif
    if (!basic_createMepTest(false))
    {
        ts_printf("Basic Local MEP creation - Test Failed.");
        overAllResult = false;
    }
    if(overAllResult == true)
    {
#ifdef DEBUG_PRINT_L2
           ts_printf("overAllResult - true\n\r");
#endif
    }
    else
    {
        ts_printf("overAllResult - false\n\r");
    }
    osSleepMS(2000);		// This is to allow the FNG thread to run and update service pending interrupts

#if 0
    if (!basicLbTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic Loopback - Test Failed.");
        overAllResult = false;
    }
#endif

#if 0
    if (!basicDmTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic Delay Measurement - Test Failed.");
        overAllResult = false;
    }
#endif

#if 0
    if (!basicLmTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic Loss Measurement - Test Failed.");
        overAllResult = false;
    }
#endif

    /*
	if (!basic_deleteMepTest())
	{
		DO_LOG_DEBUG(log_handle, "Basic Local MEP Deletion - Test Failed.");
		overAllResult = false;
	}
     */
    if (overAllResult == false)
    {
        DO_LOG_ERROR(log_handle, "***********************");
        DO_LOG_ERROR(log_handle, "One or more CFM Test Failed");
        DO_LOG_ERROR(log_handle, "***********************");
    }
    else
    {
        DO_LOG_DEBUG(log_handle, "++++++++++++++++++++++++++");
        DO_LOG_DEBUG(log_handle, " WAHOO!! All CFM tests Passed");
        DO_LOG_DEBUG(log_handle, "++++++++++++++++++++++++++");
    }
    return (overAllResult);
}

#include <api_oam_sdk/service_interface/inc/svc_iface.h>

bool basic_interfaceTest(void)
{
    svcIfaceCfg_t		svcIfaceCfg;
    svcIfaceEglCfg_t	svcIfaceEglCfg;
    svcIfaceStatus_t	svcIfaceStatus;
    iFace_t				i;
    int					retVal;

    // test interface read...
    for (i=wanPort;i<=lanPort;i++)
    {
        retVal = svcIfaceRead(i, &svcIfaceCfg, &svcIfaceEglCfg, &svcIfaceStatus);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceRead on interface %d returned %d when %d was expected",i,retVal,2);
            return false;
        }
        // Check all returned values
        if (svcIfaceCfg.svcIfaceType != bUni1d1)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d svcIfaceType returned %lu when %d was expected",i,svcIfaceCfg.svcIfaceType,bUni1d1);
            return false;
        }
        if (svcIfaceCfg.frameFormat != ff_noTag)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d frameFormat returned %lu when %d was expected",i,svcIfaceCfg.frameFormat,ff_noTag);
            return false;
        }
#if 0
        if (svcIfaceCfg.l2cpGrpIndex != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d l2cpGrpIndex returned %lu when %d was expected",i,svcIfaceCfg.l2cpGrpIndex,0);
            return false;
        }
#endif
        if (svcIfaceCfg.ingressBwpGrpIndex != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d ingressBwpGrpIndex returned %lu when %d was expected",i,svcIfaceCfg.ingressBwpGrpIndex,0);
            return false;
        }
        if (svcIfaceCfg.egressBwpGrpIndex != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d egressBwpGrpIndex returned %lu when %d was expected",i,svcIfaceCfg.egressBwpGrpIndex,0);
            return false;
        }
        if (svcIfaceEglCfg.admittance != admitAll)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d admittance returned %lu when %d was expected",i,svcIfaceEglCfg.admittance,admitAll);
            return false;
        }
        if (svcIfaceEglCfg.useDEI != false)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d admittance returned %lu when %d was expected",i,svcIfaceEglCfg.useDEI,false);
            return false;
        }
        if (strlen(svcIfaceEglCfg.vLanFilterList) != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d vLanFilterList returned %s when empty string was expected",i,svcIfaceEglCfg.vLanFilterList);
            return false;
        }
        if (strcmp(svcIfaceEglCfg.pcpEncoderMap,"0,2,4,6,8,10,12,14") != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d pcpEncoderMap returned \"%s\" when \"0,2,4,6,8,10,12,14\" was expected",i,svcIfaceEglCfg.pcpEncoderMap);
            return false;
        }
        if (strcmp(svcIfaceEglCfg.pcpDecoderMap,"0'2,1'2,2'2,3'2,4'2,5'2,6'2,7'2") != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d pcpDecoderMap returned \"%s\" when \"0'2,1'2,2'2,3'2,4'2,5'2,6'2,7'2\" was expected",i,svcIfaceEglCfg.pcpDecoderMap);
            return false;
        }
        if (strcmp(svcIfaceEglCfg.ingressDscpMap,"0:15,0:15,0:15,0:15") != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d ingressDscpMap returned \"%s\" when \"0:15,0:15,0:15,0:15\" was expected",i,svcIfaceEglCfg.ingressDscpMap);
            return false;
        }
        if (svcIfaceStatus.maxEndPointPerVc != MAX_NUM_EVCS)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d maxEndPointPerVc returned %lu when %d was expected",i,svcIfaceStatus.maxEndPointPerVc,MAX_NUM_EVCS);
            return false;
        }
        if (svcIfaceStatus.maxVc != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d maxVc returned %lu when %d was expected",i,svcIfaceStatus.maxVc,0);
            return false;
        }
        if (svcIfaceStatus.type != (bUni1d1 + bUni1d2 + bUni2d1  + bEnni))
        {
            DO_LOG_DEBUG(log_handle, "On interface %d Type returned %lu when %d was expected",i,svcIfaceStatus.type,bUni1d1 + bUni1d2 + bUni2d1  + bEnni);
            return false;
        }
    }

    svcIfaceType_t	ifaceType;
    frameFormat_t	frameFormat;
    bwpGrpIndex_t	ingressBwpGrpIndex;
    //l2cpGrpIndex_t	l2cpGrpIndex;
    char			pcpEncoderMap[32];		// Defines the ingress COS mapping for the interface (default = "0,2,4,6,8,10,12,14")
    char			pcpDecoderMap[32];		// Defines the egress COS mapping for the interface  (default = "0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7")
    char			ingressDscpMap[128];	// Defines the ingress DSCP mapping for the interface (default = ??)
    char			vLanFilterList[256];	// A List of all VLan that should be filtered (dropped) at the interface (default = "")
    admittance_t	admittance;				// Defines the admittance rules for ingress packets	(default = admitAll)
    bool			useDEI;

    // test interface write...
    for (i=wanPort;i<=lanPort;i++)
    {
        // Write to an invalid interface
        retVal = svcIfaceWrite(4, ifaceParam_svcIfaceType, &ifaceType);
        if (retVal != 1)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite on interface %d returned %d when %d was expected",4,retVal,1);
            return false;
        }

        // Write to an invalid parameter index
        retVal = svcIfaceWrite(i, 25, &ifaceType);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite on interface %d returned %d when %d was expected",i,retVal,2);
            return false;
        }

        // --------------------------- svcIfaceWrite:ifaceParam_svcIfaceType ----------------------
        // Write an invalid value...
        ifaceType = 0;
        retVal = svcIfaceWrite(i, ifaceParam_svcIfaceType, &ifaceType);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ifaceType on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }

        // Write an invalid value...
        ifaceType = 64;
        retVal = svcIfaceWrite(i, ifaceParam_svcIfaceType, &ifaceType);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ifaceType on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }

        // Write an invalid value...
        ifaceType = bEnniVuni;
        retVal = svcIfaceWrite(i, ifaceParam_svcIfaceType, &ifaceType);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ifaceType on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }

        // Write an valid value...
        ifaceType = bUni1d1;
        retVal = svcIfaceWrite(i, ifaceParam_svcIfaceType, &ifaceType);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ifaceType on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // --------------------------- svcIfaceWrite: ifaceParam_frameFormat ----------------------
        // Write an invalid value...
        frameFormat = 0;
        retVal = svcIfaceWrite(i, ifaceParam_frameFormat, &frameFormat);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite frameFormat on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }

        // Write an invalid value...
        frameFormat = 64;
        retVal = svcIfaceWrite(i, ifaceParam_frameFormat, &frameFormat);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite frameFormat on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }

        // Write an valid value...
        frameFormat = ff_stag;
        retVal = svcIfaceWrite(i, ifaceParam_frameFormat, &frameFormat);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite frameFormat on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // --------------------------- svcIfaceWrite: ifaceParam_ingressBwpGrpIndex ----------------------
        // Write an invalid value...
        ingressBwpGrpIndex = 10;
        retVal = svcIfaceWrite(i, ifaceParam_ingressBwpGrpIndex, &ingressBwpGrpIndex);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ingressBwpGrpIndex on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }

        // Write an valid value...
        ingressBwpGrpIndex = 0;
        retVal = svcIfaceWrite(i, ifaceParam_ingressBwpGrpIndex, &ingressBwpGrpIndex);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ingressBwpGrpIndex on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
#if 0
        // --------------------------- svcIfaceWrite: ifaceParam_l2cpGrpIndex ----------------------
        // Write an invalid value...
        l2cpGrpIndex = 10;
        retVal = svcIfaceWrite(i, ifaceParam_l2cpGrpIndex, &l2cpGrpIndex);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite l2cpGrpIndex on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }

        // Write an valid value...
        l2cpGrpIndex = 0;
        retVal = svcIfaceWrite(i, ifaceParam_l2cpGrpIndex, &l2cpGrpIndex);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite l2cpGrpIndex on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
#endif
        // --------------------------- svcIfaceWrite: ifaceParam_pcpEncoderMap ----------------------
        // Write an invalid value...
        sprintf(pcpEncoderMap,"9:1");
        retVal = svcIfaceWrite(i, ifaceParam_pcpEncoderMap, pcpEncoderMap);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpEncoderMap on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }
        // Write an invalid value...
        sprintf(pcpEncoderMap,"7:1");
        retVal = svcIfaceWrite(i, ifaceParam_pcpEncoderMap, pcpEncoderMap);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpEncoderMap on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }
        // Write an invalid value...
        sprintf(pcpEncoderMap,"0:9");		// list length must be 8
        retVal = svcIfaceWrite(i, ifaceParam_pcpEncoderMap, pcpEncoderMap);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpEncoderMap on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }
        // Write an invalid value...
        sprintf(pcpEncoderMap,"0,1,2,3,4,5,6,7,8");		// list length must be 8
        retVal = svcIfaceWrite(i, ifaceParam_pcpEncoderMap, pcpEncoderMap);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpEncoderMap on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }
        // Write an invalid value...
        sprintf(pcpEncoderMap,"66");
        retVal = svcIfaceWrite(i, ifaceParam_pcpEncoderMap, pcpEncoderMap);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpEncoderMap on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }

        // Write a valid value...
        sprintf(pcpEncoderMap,"0:7");
        retVal = svcIfaceWrite(i, ifaceParam_pcpEncoderMap, pcpEncoderMap);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpEncoderMap on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }

        // Write a valid value...
        sprintf(pcpEncoderMap,"0'2,1'2,14'2,15'2");
        retVal = svcIfaceWrite(i, ifaceParam_pcpEncoderMap, pcpEncoderMap);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpEncoderMap on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }

        // Write a valid value...
        sprintf(pcpEncoderMap,"0,2,4,6,8,10,12,14");
        retVal = svcIfaceWrite(i, ifaceParam_pcpEncoderMap, pcpEncoderMap);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpEncoderMap on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // --------------------------- svcIfaceWrite: ifaceParam_pcpDecoderMap ----------------------
        // Write an invalid value...
        sprintf(pcpDecoderMap,"7:1");
        retVal = svcIfaceWrite(i, ifaceParam_pcpDecoderMap, pcpDecoderMap);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpDecoderMap on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }

        // Write an invalid value...
        sprintf(pcpDecoderMap,"1:8");
        retVal = svcIfaceWrite(i, ifaceParam_pcpDecoderMap, pcpDecoderMap);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpDecoderMap on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }

        // Write a valid value...
        sprintf(pcpDecoderMap,"0:7,7:0");
        retVal = svcIfaceWrite(i, ifaceParam_pcpDecoderMap, pcpDecoderMap);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpDecoderMap on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }

        // Write a valid value...
        sprintf(pcpDecoderMap,"0'4,1'4,6'4,7'4");
        retVal = svcIfaceWrite(i, ifaceParam_pcpDecoderMap, pcpDecoderMap);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpDecoderMap on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }

        // Write a valid value...
        sprintf(pcpDecoderMap,"0'2,1'2,2'2,3'2,4'2,5'2,6'2,7'2");
        retVal = svcIfaceWrite(i, ifaceParam_pcpDecoderMap, pcpDecoderMap);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite pcpDecoderMap on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // --------------------------- svcIfaceWrite: ifaceParam_pcpDecoderMap ----------------------
        // Write an invalid value...
        sprintf(ingressDscpMap,"7:1");
        retVal = svcIfaceWrite(i, ifaceParam_ingressDscpMap, ingressDscpMap);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ingressDscpMap on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }
        // Write an invalid value...
        sprintf(ingressDscpMap,"66:1");
        retVal = svcIfaceWrite(i, ifaceParam_ingressDscpMap, ingressDscpMap);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ingressDscpMap on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }
        // Write an valid value...
        sprintf(ingressDscpMap,"1'64");
        retVal = svcIfaceWrite(i, ifaceParam_ingressDscpMap, ingressDscpMap);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ingressDscpMap on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // Write an valid value...
        sprintf(ingressDscpMap,"0:7,0:7,0:7,0:7,0:7,0:7,0:7,0:7");
        retVal = svcIfaceWrite(i, ifaceParam_ingressDscpMap, ingressDscpMap);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ingressDscpMap on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // Write an valid value...
        sprintf(ingressDscpMap,"0'8,1'8,x'8,3'8,4'8,x'8,6'8,7'8");
        retVal = svcIfaceWrite(i, ifaceParam_ingressDscpMap, ingressDscpMap);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ingressDscpMap on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // Write an valid value...
        sprintf(ingressDscpMap,"0'8,1'8,2'8,3'8,4'8,5'8,6'8,7'8");
        retVal = svcIfaceWrite(i, ifaceParam_ingressDscpMap, ingressDscpMap);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite ingressDscpMap on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // --------------------------- svcIfaceWrite: ifaceParam_vLanFilterList ----------------------
        // Write an invalid value...
        sprintf(vLanFilterList,"4099");
        retVal = svcIfaceWrite(i, ifaceParam_vLanFilterList, vLanFilterList);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite vLanFilterList on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }
        // Write a valid value...
        sprintf(vLanFilterList,"0");
        retVal = svcIfaceWrite(i, ifaceParam_vLanFilterList, vLanFilterList);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite vLanFilterList on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
#if 0	// TODO: This takes a very long time to run...must investigate more
        // Write a valid value...
        sprintf(vLanFilterList,"1:4095");
        retVal = svcIfaceWrite(i, ifaceParam_vLanFilterList, vLanFilterList);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite vLanFilterList on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
#endif
        // Write a valid value...
        sprintf(vLanFilterList,"1:10");
        retVal = svcIfaceWrite(i, ifaceParam_vLanFilterList, vLanFilterList);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite vLanFilterList on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // Write a valid value...
        sprintf(vLanFilterList,"1,3,5,7,11");
        retVal = svcIfaceWrite(i, ifaceParam_vLanFilterList, vLanFilterList);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite vLanFilterList on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // Write a valid value...
        memset(vLanFilterList,0,1); // = ""
        retVal = svcIfaceWrite(i, ifaceParam_vLanFilterList, vLanFilterList);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite vLanFilterList on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // --------------------------- svcIfaceWrite: ifaceParam_admittance ----------------------
        // Write an invalid value...
        admittance = 0;
        retVal = svcIfaceWrite(i, ifaceParam_admittance, &admittance);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite admittance on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }
        // Write an invalid value...
        admittance = 20;
        retVal = svcIfaceWrite(i, ifaceParam_admittance, &admittance);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite admittance on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }
        // Write a valid value...
        admittance = admitPrioUntaggedOnly;
        retVal = svcIfaceWrite(i, ifaceParam_admittance, &admittance);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite admittance on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // Write a valid value...
        admittance = admitAll;
        retVal = svcIfaceWrite(i, ifaceParam_admittance, &admittance);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite admittance on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // --------------------------- svcIfaceWrite: ifaceParam_useDEI ----------------------
        // Write an invalid value...
        retVal = svcIfaceWrite(i, ifaceParam_useDEI, NULL);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite useDEI on interface %d returned %d when %d was expected",i,retVal,3);
            return false;
        }
        // Write a valid value...
        useDEI = true;
        retVal = svcIfaceWrite(i, ifaceParam_useDEI, &useDEI);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite useDEI on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // Write a valid value...
        useDEI = false;
        retVal = svcIfaceWrite(i, ifaceParam_useDEI, &useDEI);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceWrite useDEI on interface %d returned %d when %d was expected",i,retVal,4);
            return false;
        }
        // --------------------------- svcIfaceRead ---------------------------
        retVal = svcIfaceRead(i, &svcIfaceCfg, &svcIfaceEglCfg, &svcIfaceStatus);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "svcIfaceRead on interface %d returned %d when %d was expected",i,retVal,2);
            return false;
        }
        // Check all returned values
        if (svcIfaceCfg.svcIfaceType != ifaceType)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d svcIfaceType returned %lu when %d was expected",i,svcIfaceCfg.svcIfaceType,ifaceType);
            return false;
        }
        if (svcIfaceCfg.frameFormat != frameFormat)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d frameFormat returned %lu when %d was expected",i,svcIfaceCfg.frameFormat,frameFormat);
            return false;
        }
#if 0
        if (svcIfaceCfg.l2cpGrpIndex != l2cpGrpIndex)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d l2cpGrpIndex returned %lu when %d was expected",i,svcIfaceCfg.l2cpGrpIndex,l2cpGrpIndex);
            return false;
        }
#endif
        if (svcIfaceCfg.ingressBwpGrpIndex != ingressBwpGrpIndex)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d ingressBwpGrpIndex returned %lu when %d was expected",i,svcIfaceCfg.ingressBwpGrpIndex,ingressBwpGrpIndex);
            return false;
        }
        if (svcIfaceCfg.egressBwpGrpIndex != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d egressBwpGrpIndex returned %lu when %d was expected",i,svcIfaceCfg.egressBwpGrpIndex,0);
            return false;
        }
        if (svcIfaceEglCfg.admittance != admittance)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d admittance returned %lu when %d was expected",i,svcIfaceEglCfg.admittance,admittance);
            return false;
        }
        if (svcIfaceEglCfg.useDEI != useDEI)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d admittance returned %lu when %d was expected",i,svcIfaceEglCfg.useDEI,useDEI);
            return false;
        }
        if (strcmp(svcIfaceEglCfg.vLanFilterList,vLanFilterList) != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d vLanFilterList returned %s when \"%s\" was expected",i,svcIfaceEglCfg.vLanFilterList,vLanFilterList);
            return false;
        }
        if (strcmp(svcIfaceEglCfg.pcpEncoderMap,pcpEncoderMap) != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d pcpEncoderMap returned \"%s\" when \"%s\" was expected",i,svcIfaceEglCfg.pcpEncoderMap,pcpEncoderMap);
            return false;
        }
        if (strcmp(svcIfaceEglCfg.pcpDecoderMap,pcpDecoderMap) != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d pcpDecoderMap returned \"%s\" when \"%s\" was expected",i,svcIfaceEglCfg.pcpDecoderMap,pcpDecoderMap);
            return false;
        }
        if (strcmp(svcIfaceEglCfg.ingressDscpMap,ingressDscpMap) != 0)
        {
            DO_LOG_DEBUG(log_handle, "On interface %d ingressDscpMap returned \"%s\" when \"%s\" was expected",i,svcIfaceEglCfg.ingressDscpMap,ingressDscpMap);
            return false;
        }
    }
    return true;
}

bool basic_uniTest(void)
{
    int			retVal;
    iFace_t 	uni;
    svcUniCfg_t svcUniCfg;
    svcUniCfg_t	svcUniCfgRd;

    retVal = svcUniCreate(3, &svcUniCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcUniCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    uni = wanPort;
    retVal = svcUniCreate(uni, NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcUniCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    svcUniCfg.bundlingMultiplex = 10;
    svcUniCfg.cePriorityUntaged = 10;
    svcUniCfg.ceVlanUntagged = 6000;
    retVal = svcUniCreate(uni, &svcUniCfg);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcUniCreate returned %d when %d was expected",retVal,2);
        return false;
    }
    svcUniCfg.bundlingMultiplex = 0;
    retVal = svcUniCreate(uni, &svcUniCfg);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcUniCreate returned %d when %d was expected",retVal,2);
        return false;
    }
    svcUniCfg.bundlingMultiplex = allToOne;
    retVal = svcUniCreate(uni, &svcUniCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcUniCreate returned %d when %d was expected",retVal,3);
        return false;
    }
    svcUniCfg.ceVlanUntagged = 10;
    retVal = svcUniCreate(uni, &svcUniCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcUniCreate returned %d when %d was expected",retVal,4);
        return false;
    }
    svcUniCfg.cePriorityUntaged = prio4;
    retVal = svcUniCreate(uni, &svcUniCfg);
    if (retVal != 5)
    {
        DO_LOG_DEBUG(log_handle, "svcUniCreate returned %d when %d was expected",retVal,5);
        return false;
    }

    // Try to re-create the same UNI
    retVal = svcUniCreate(uni, &svcUniCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcUniCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    //-----------------------------  svcUniRead
    retVal = svcUniRead(10, &svcUniCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcUniRead returned %d when %d was expected",retVal,1);
        return false;
    }
    //	retVal = svcUniRead(lanPort, &svcUniCfg);
    //	if (retVal != 2)
    //	{
    //		DO_LOG_DEBUG(log_handle, "svcUniRead returned %d when %d was expected",retVal,2);
    //		return false;
    //	}
    retVal = svcUniRead(uni, &svcUniCfgRd);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcUniRead returned %d when %d was expected",retVal,2);
        return false;
    }

    if (svcUniCfgRd.bundlingMultiplex != svcUniCfg.bundlingMultiplex)
    {
        DO_LOG_DEBUG(log_handle, "svcUniRead:bundlingMultiplex returned %d when %d was expected",svcUniCfgRd.bundlingMultiplex != svcUniCfg.bundlingMultiplex);
        return false;
    }
    if (svcUniCfgRd.ceVlanUntagged != svcUniCfg.ceVlanUntagged)
    {
        DO_LOG_DEBUG(log_handle, "svcUniRead:ceVlanUntagged returned %d when %d was expected",svcUniCfgRd.ceVlanUntagged != svcUniCfg.ceVlanUntagged);
        return false;
    }
    if (svcUniCfgRd.cePriorityUntaged != svcUniCfg.cePriorityUntaged)
    {
        DO_LOG_DEBUG(log_handle, "svcUniRead:cePriorityUntaged returned %d when %d was expected",svcUniCfgRd.cePriorityUntaged != svcUniCfg.cePriorityUntaged);
        return false;
    }

    // --------------------------- svcUniDelete
    retVal = svcUniDelete(10);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcUniDelete returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcUniDelete(lanPort);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcUniDelete returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcUniDelete(uni);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcUniDelete returned %d when %d was expected",retVal,2);
        return false;
    }
    return true;
}

bool basic_evcTest(void)
{
    evcPerUniWrParam_t wrParam;
    uint32_t	param;
    evcIndex_t	evcIndex;
    evcCfg_t	evcCfg;
    evcCfg_t	evcCfgRd;
    evcStatus_t evcStatus;
    int			retVal;

    evcIndex = svcEvcReadList(1);
    if (evcIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcGetNextIndex returned %d when %d was expected",evcIndex,0);
        return false;
    }

    evcIndex = svcEvcReadList(0);
    if (evcIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcGetNextIndex returned %d when %d was expected",evcIndex,0);
        return false;
    }

    evcCfg.adminState				= state_locked;
    evcCfg.ceVlanCosPreservation	= preserve;
    evcCfg.ceVlanIdPreservation		= preserve;
    evcCfg.evcServiceType			= evcType_pointToPoint;
    evcCfg.mtuSize					= 9600;
    evcIndex = svcEvcGetNextIndex();
    if (evcIndex != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcGetNextIndex returned %d when %d was expected",evcIndex,1);
        return false;
    }

    retVal = svcEvcCreate(0, &evcCfg);
    if (retVal != -1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcCreate returned %d when %d was expected",retVal,-1);
        return false;
    }

    retVal = svcEvcCreate(evcIndex, NULL);
    if (retVal != -2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcCreate returned %d when %d was expected",retVal,-2);
        return false;
    }

    // Wrong type...
    evcCfg.evcServiceType = 60;
    retVal = svcEvcCreate(evcIndex, &evcCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcCreate returned %d when %d was expected",retVal,1);
        return false;
    }
    evcCfg.evcServiceType			= evcType_pointToPoint;

    // Wrong mtuSize...
    evcCfg.mtuSize = 10000;
    retVal = svcEvcCreate(evcIndex, &evcCfg);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcCreate returned %d when %d was expected",retVal,2);
        return false;
    }
    evcCfg.mtuSize					= 9600;

    // Wrong l2cpGrpIndex...
    evcCfg.l2cpGrpIndex = 10;
    retVal = svcEvcCreate(evcIndex, &evcCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcCreate returned %d when %d was expected",retVal,3);
        return false;
    }
    evcCfg.l2cpGrpIndex	= 0;

    // Wrong l2cpGrpIndex...
    evcCfg.adminState = 10;
    retVal = svcEvcCreate(evcIndex, &evcCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcCreate returned %d when %d was expected",retVal,4);
        return false;
    }
    evcCfg.adminState = state_unlocked;

    // create a good EVC...
    retVal = svcEvcCreate(evcIndex, &evcCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcCreate returned %d when %d was expected",retVal,4);
        return false;
    }

    // Read a bad EVC index...
    retVal = svcEvcRead(0, &evcCfg, &evcStatus);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead returned %d when %d was expected",retVal,1);
        return false;
    }

    // Read a good EVC, but use NULL ...
    retVal = svcEvcRead(evcIndex, NULL, &evcStatus);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead returned %d when %d was expected",retVal,2);
        return false;
    }

    // Read a good EVC, but use NULL ...
    retVal = svcEvcRead(evcIndex, &evcCfg, NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead returned %d when %d was expected",retVal,2);
        return false;
    }

    // Read a good EVC...
    retVal = svcEvcRead(evcIndex, &evcCfg, &evcStatus);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead returned %d when %d was expected",retVal,2);
        return false;
    }

    // Delete wrong EVC index...
    retVal = svcEvcDelete(0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcDelete returned %d when %d was expected",retVal,1);
        return false;
    }

    // Delete EVC...
    retVal = svcEvcDelete(evcIndex);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcDelete returned %d when %d was expected",retVal,2);
        return false;
    }

    // Read deleted EVC...
    retVal = svcEvcRead(evcIndex, &evcCfg, &evcStatus);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead returned %d when %d was expected",retVal,1);
        return false;
    }

    evcIndex = svcEvcGetNextIndex();
    if (evcIndex != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcGetNextIndex returned %d when %d was expected",evcIndex,2);
        return false;
    }

    // create a good EVC...
    retVal = svcEvcCreate(evcIndex, &evcCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcCreate returned %d when %d was expected",retVal,4);
        return false;
    }

    // Read a good EVC...
    retVal = svcEvcRead(evcIndex, &evcCfgRd, &evcStatus);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead returned %d when %d was expected",retVal,2);
        return false;
    }

    // Check all read values
    if (evcCfgRd.adminState != evcCfg.adminState)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead: adminState returned %d when %d was expected",evcCfgRd.adminState, evcCfg.adminState);
        return false;
    }
    if (evcCfgRd.ceVlanCosPreservation != evcCfg.ceVlanCosPreservation)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead: ceVlanCosPreservation returned %d when %d was expected",evcCfgRd.ceVlanCosPreservation, evcCfg.ceVlanCosPreservation);
        return false;
    }
    if (evcCfgRd.ceVlanIdPreservation != evcCfg.ceVlanIdPreservation)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead: ceVlanIdPreservation returned %d when %d was expected",evcCfgRd.ceVlanIdPreservation, evcCfg.ceVlanIdPreservation);
        return false;
    }
    if (evcCfgRd.evcServiceType != evcCfg.evcServiceType)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead: evcServiceType returned %d when %d was expected",evcCfgRd.evcServiceType, evcCfg.evcServiceType);
        return false;
    }
    if (evcCfgRd.l2cpGrpIndex != evcCfg.l2cpGrpIndex)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead: l2cpGrpIndex returned %d when %d was expected",evcCfgRd.l2cpGrpIndex, evcCfg.l2cpGrpIndex);
        return false;
    }
    if (evcCfgRd.mtuSize != evcCfg.mtuSize)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead: mtuSize returned %d when %d was expected",evcCfgRd.mtuSize, evcCfg.mtuSize);
        return false;
    }

    uint32_t		mtuSize = 10;
    l2cpGrpIndex_t	l2cpGrpIndex = 2;
    //----------------- svcEvcWrite evcParam_mtuSize
    // write wrong index...
    retVal = svcEvcWrite(0, evcParam_mtuSize, &mtuSize);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcWrite returned %d when %d was expected",retVal,1);
        return false;
    }

    // write wrong param index...
    retVal = svcEvcWrite(evcIndex, 0, &mtuSize);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcWrite returned %d when %d was expected",retVal,2);
        return false;
    }

    // write wrong param index...
    retVal = svcEvcWrite(evcIndex, 10, &mtuSize);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcWrite returned %d when %d was expected",retVal,2);
        return false;
    }

    // write wrong param index...
    retVal = svcEvcWrite(evcIndex, evcParam_mtuSize, NULL);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcWrite returned %d when %d was expected",retVal,3);
        return false;
    }

    // write wrong param index...
    mtuSize = 10000;
    retVal = svcEvcWrite(evcIndex, evcParam_mtuSize, &mtuSize);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcWrite returned %d when %d was expected",retVal,3);
        return false;
    }

    // write good param...
    mtuSize = 9000;
    retVal = svcEvcWrite(evcIndex, evcParam_mtuSize, &mtuSize);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcWrite returned %d when %d was expected",retVal,4);
        return false;
    }

    //----------------- svcEvcWrite evcParam_l2cpGrpIndex
    // write wrong param value...
    retVal = svcEvcWrite(evcIndex, evcParam_l2cpGrpIndex, &l2cpGrpIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead returned %d when %d was expected",retVal,3);
        return false;
    }

    l2cpGrpIndex = 0;
    retVal = svcEvcWrite(evcIndex, evcParam_l2cpGrpIndex, &l2cpGrpIndex);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcRead returned %d when %d was expected",retVal,4);
        return false;
    }
    //----------------- svcEvcUniRead
    iFace_t		iFace = wanPort;
    evcUniCfg_t	evcUniCfg;


    retVal = svcEvcUniRead(4,evcIndex, &evcUniCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcUniRead returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcEvcUniRead(iFace,4, &evcUniCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcUniRead returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcEvcUniRead(iFace,evcIndex, NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcUniRead returned %d when %d was expected",retVal,2);
        return false;
    }
    retVal = svcEvcUniRead(iFace,evcIndex, &evcUniCfg);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcUniRead returned %d when %d was expected",retVal,2);
        return false;
    }

    if (evcUniCfg.evcUniType != eu_unknown)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcUniRead returned %d when %d was expected",evcUniCfg.evcUniType,eu_unknown);
        return false;
    }

    //----------------- svcEvcUniWrite
    evcUniType_t	evcUniType = 0;

    retVal = svcEvcUniWrite(4,evcIndex, evcUniParam_evcUniType, &evcUniType);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcUniWrite returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcEvcUniWrite(iFace,4, evcUniParam_evcUniType, &evcUniType);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcUniWrite returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcEvcUniWrite(iFace,evcIndex, 4, &evcUniType);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcUniWrite returned %d when %d was expected",retVal,2);
        return false;
    }
    retVal = svcEvcUniWrite(iFace,evcIndex, evcUniParam_evcUniType, &evcUniType);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcUniWrite returned %d when %d was expected",retVal,3);
        return false;
    }
    evcUniType = eu_root;
    retVal = svcEvcUniWrite(iFace,evcIndex, evcUniParam_evcUniType, &evcUniType);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcUniWrite returned %d when %d was expected",retVal,4);
        return false;
    }
    //----------------------------------------------
    evcPerUniCfg_t		evcPerUniCfg;
    evcPerUniEglCfg_t	evcPerUniEglCfg;
    retVal = svcEvcPerUniRead(4, evcIndex, NULL, NULL);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcEvcPerUniRead(wanPort, 4, NULL, NULL);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcEvcPerUniRead(wanPort, evcIndex, NULL, NULL);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead returned %d when %d was expected",retVal,2);
        return false;
    }
    retVal = svcEvcPerUniRead(wanPort, evcIndex, &evcPerUniCfg, &evcPerUniEglCfg);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead returned %d when %d was expected",retVal,2);
        return false;
    }

    if (strlen(evcPerUniCfg.ceVlanMap) > 0)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead: ceVlanMap returned %s when \"\" was expected",evcPerUniCfg.ceVlanMap);
        return false;
    }
    if (evcPerUniCfg.serviceType != st_epl)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead: serviceType returned %d when %d was expected",evcPerUniCfg.serviceType,st_epl);
        return false;
    }
    if (evcPerUniCfg.ingressBwpGrpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead: ingressBwpGrpIndex returned %d when %d was expected",evcPerUniCfg.ingressBwpGrpIndex,0);
        return false;
    }
    if (evcPerUniCfg.egressBwpGrpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead: egressBwpGrpIndex returned %d when %d was expected",evcPerUniCfg.egressBwpGrpIndex,0);
        return false;
    }

    if (evcPerUniEglCfg.outerTagVLan != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead: outerTagVLan returned %d when %d was expected",evcPerUniEglCfg.outerTagVLan,0);
        return false;
    }
    if (evcPerUniEglCfg.tagAction != ta_noAction)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead: tagAction returned %d when %d was expected",evcPerUniEglCfg.tagAction,ta_noAction);
        return false;
    }
    if (evcPerUniEglCfg.tagType != pushCtag)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniRead: tagType returned %d when %d was expected",evcPerUniEglCfg.tagType,pushCtag);
        return false;
    }

    // invalid iface...
    wrParam = 20;
    retVal = svcEvcPerUniWrite(10,evcIndex,wrParam,&param);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,1);
        return false;
    }
    // invalid evcIndex...
    retVal = svcEvcPerUniWrite(wanPort,0,wrParam,&param);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,1);
        return false;
    }
    // invalid param Index...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,10,&param);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,2);
        return false;
    }
    // -------------------------------- svcEvcPerUniWrite evcPerUniParam_serviceType
    // invalid param Index...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_serviceType,NULL);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,3);
        return false;
    }
    serviceType_t	serviceType = 10;
    // invalid param value...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_serviceType,&serviceType);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,3);
        return false;
    }
    // valid param value...
    serviceType = st_evpl;
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_serviceType,&serviceType);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,4);
        return false;
    }
    // -------------------------------- svcEvcPerUniWrite evcPerUniParam_ceVlanMap
    char	ceVlanMap[256];
    strcpy(ceVlanMap,"a:b,c:d");
    // invalid param Index...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_ceVlanMap,ceVlanMap);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,3);
        return false;
    }

    strcpy(ceVlanMap,"1,3,5,6:10");
    // invalid param Index...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_ceVlanMap,ceVlanMap);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,4);
        return false;
    }

    strcpy(ceVlanMap,"6:10,12,15");
    // invalid param Index...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_ceVlanMap,ceVlanMap);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,4);
        return false;
    }

#if 1 // takes 30sec to run for 4095 vlans!!!
    strcpy(ceVlanMap,"1:4095");
    // invalid param Index...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_ceVlanMap,ceVlanMap);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,4);
        return false;
    }
#endif

    // -------------------------------- svcEvcPerUniWrite evcPerUniParam_ingressBwpGrpIndex
    bwpGrpIndex_t	bwpGrpIndex = 10;
    // invalid param value...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_ingressBwpGrpIndex,&bwpGrpIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,3);
        return false;
    }
    // valid param value...
    bwpGrpIndex = 0;
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_ingressBwpGrpIndex,&bwpGrpIndex);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,4);
        return false;
    }
    // -------------------------------- svcEvcPerUniWrite evcPerUniParam_outerTagVLan
    uint16_t	outerTagVLan = 4096;
    // invalid param value...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_outerTagVLan,&outerTagVLan);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,3);
        return false;
    }
    outerTagVLan = 10;
    // invalid param value...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_outerTagVLan,&outerTagVLan);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,4);
        return false;
    }
    // -------------------------------- svcEvcPerUniWrite evcPerUniParam_tagAction
    tagAction_t	tagAction = 10;
    // invalid param value...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_tagAction,&tagAction);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,3);
        return false;
    }
    tagAction = ta_tagOverwrite;
    // invalid param value...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_tagAction,&tagAction);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,4);
        return false;
    }
    // -------------------------------- svcEvcPerUniWrite evcPerUniParam_tagType
    pushTag_t	tagType = 10;
    // invalid param value...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_tagType,&tagType);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,3);
        return false;
    }
    tagType = pushStag;
    // invalid param value...
    retVal = svcEvcPerUniWrite(wanPort,evcIndex,evcPerUniParam_tagType,&tagType);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcEvcPerUniWrite returned %d when %d was expected",retVal,4);
        return false;
    }
    return true;
}

bool basic_cosTest(void)
{
    int retVal;
    int	k;
    cosIndex_t	cosIndexNext;
    cosIndex_t	cosIndex;
    svcCosCfg_t svcCosCfg,svcCosCfgRd;
    svcCosEglCfg_t svcCosEglCfg,svcCosEglCfgRd;

    cosIndexNext = svcCosGetNextIndex();
    if (cosIndexNext != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosGetNextIndex returned %d when %d was expected",cosIndexNext,1);
        return false;
    }

    cosIndex = svcCosReadList(0);
    if (cosIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcCosReadList returned %d when %d was expected",cosIndex,0);
        return false;
    }

    retVal = svcCosDelete(0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosDelete returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcCosDelete(cosIndexNext);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosDelete returned %d when %d was expected",retVal,1);
        return false;
    }

    svcCosCfg.cosType = cosType_interface;
    strcpy(svcCosCfg.identifierList,"0:7");
    memset(svcCosCfg.macAddress,0,6);
    svcCosCfg.protocol = 0;
    svcCosCfg.subType = 0;

    svcCosEglCfg.colourAware = true;
    svcCosEglCfg.colourForward = true;
    strcpy(svcCosEglCfg.colourMap,"0'8");
    svcCosEglCfg.outerTagCos = prio4;

    retVal = svcCosCreate(0, &svcCosCfg, &svcCosEglCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcCosCreate(cosIndexNext, NULL, &svcCosEglCfg);
    if (retVal != -1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,-1);
        return false;
    }

    retVal = svcCosCreate(cosIndexNext, &svcCosCfg, NULL);
    if (retVal != -1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,-1);
        return false;
    }


    svcCosCfg.cosType = 0;
    retVal = svcCosCreate(cosIndexNext, &svcCosCfg, &svcCosEglCfg);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,2);
        return false;
    }
    svcCosCfg.cosType = 10;
    retVal = svcCosCreate(cosIndexNext, &svcCosCfg, &svcCosEglCfg);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,2);
        return false;
    }
    svcCosCfg.cosType = cosType_interface;

    strcpy(svcCosCfg.identifierList,"16:7");
    retVal = svcCosCreate(cosIndexNext, &svcCosCfg, &svcCosEglCfg);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,3);
        return false;
    }
    strcpy(svcCosCfg.identifierList,"0:7");

    strcpy(svcCosEglCfg.colourMap,"2'8");
    retVal = svcCosCreate(cosIndexNext, &svcCosCfg, &svcCosEglCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,4);
        return false;
    }
    strcpy(svcCosEglCfg.colourMap,"0'8");

    retVal = svcCosCreate(cosIndexNext, &svcCosCfg, &svcCosEglCfg);
    if (retVal != 5)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,5);
        return false;
    }

    // attempt to re-create the same COS
    retVal = svcCosCreate(cosIndexNext, &svcCosCfg, &svcCosEglCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    cosIndex = cosIndexNext;

    retVal = svcCosDelete(cosIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcCosDelete returned %d when %d was expected",retVal,3);
        return false;
    }

    for (k=0;k<MAX_NUM_COS;k++)
    {
        retVal = svcCosCreate(k+1, &svcCosCfg, &svcCosEglCfg);
        if (retVal != 5)
        {
            DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,5);
            return false;
        }
    }

    retVal = svcCosCreate(svcCosGetNextIndex(), &svcCosCfg, &svcCosEglCfg);
    if (retVal != -2)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,-2);
        return false;
    }

    for (k=0;k<MAX_NUM_COS;k++)
    {
        retVal = svcCosDelete(k+1);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcCosDelete returned %d when %d was expected",retVal,3);
            return false;
        }
    }

    cosIndex = 1;
    retVal = svcCosCreate(cosIndex, &svcCosCfg, &svcCosEglCfg);
    if (retVal != 5)
    {
        DO_LOG_DEBUG(log_handle, "svcCosCreate returned %d when %d was expected",retVal,5);
        return false;
    }

    //-------------
    retVal = svcCosRead(0, &svcCosCfgRd, &svcCosEglCfgRd);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosRead returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcCosRead(2, &svcCosCfgRd, &svcCosEglCfgRd);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosRead returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcCosRead(cosIndex, &svcCosCfgRd, &svcCosEglCfgRd);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcCosRead returned %d when %d was expected",retVal,2);
        return false;
    }
    //-------------
    //confirm all read back values...
    //-------------

    retVal = svcCosWrite(0, cosParam_cosIdentifierList, &svcCosEglCfgRd);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosWrite returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcCosWrite(2, cosParam_cosIdentifierList, &svcCosEglCfgRd);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcCosWrite returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcCosWrite(cosIndex, cosParam_cosIdentifierList, &svcCosCfg.identifierList);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcCosWrite returned %d when %d was expected",retVal,4);
        return false;
    }
    // TODO: add tests for other parameters...
    return true;
}

bool basic_bwpTest(void)
{
    bwpGrpIndex_t	bwpGrpIndex,bwpGrpIndexNext;
    int		retVal;
    int k;

    bwpGrpIndexNext	= svcBwpGrpGetNextIndex();
    if (bwpGrpIndexNext != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpGetNextIndex returned %d when %d was expected",bwpGrpIndexNext,1);
        return false;
    }

    bwpGrpIndex = svcBwpGrpReadList(0);
    if (bwpGrpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpReadList returned %d when %d was expected",bwpGrpIndex,0);
        return false;
    }

    retVal = svcBwpGrpCreate(0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcBwpGrpCreate(bwpGrpIndexNext);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpCreate returned %d when %d was expected",retVal,2);
        return false;
    }

    // attempt to re-create the same BWP Group
    retVal = svcBwpGrpCreate(bwpGrpIndexNext);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    bwpGrpIndex = svcBwpGrpReadList(0);
    if (bwpGrpIndex != bwpGrpIndexNext)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpReadList returned %d when %d was expected",bwpGrpIndex,bwpGrpIndexNext);
        return false;
    }

    retVal = svcBwpGrpDelete(0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpDelete returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcBwpGrpDelete(bwpGrpIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpDelete returned %d when %d was expected",retVal,3);
        return false;
    }

    bwpGrpIndex = 1;
    retVal = svcBwpGrpCreate(bwpGrpIndex);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpCreate returned %d when %d was expected",retVal,2);
        return false;
    }

    bwpGrpIndex = 10;
    retVal = svcBwpGrpCreate(bwpGrpIndex);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpCreate returned %d when %d was expected",retVal,2);
        return false;
    }

    retVal = svcBwpGrpDelete(bwpGrpIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpDelete returned %d when %d was expected",retVal,3);
        return false;
    }

    bwpIndex_t	bwpIndex,bwpIndexNext;
    bwpGrpIndex = 1;
    bwpIndex =	svcBwpGetNextBwpIndex(0);
    if (bwpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGetNextBwpIndex returned %d when %d was expected",bwpIndex,0);
        return false;
    }

    bwpIndexNext =	svcBwpGetNextBwpIndex(bwpGrpIndex);
    if (bwpIndexNext != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGetNextBwpIndex returned %d when %d was expected",bwpIndexNext,1);
        return false;
    }

    bwpIndex = svcBwpReadList(0,0);
    if (bwpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpReadList returned %d when %d was expected",bwpIndex,0);
        return false;
    }

    bwpIndex = svcBwpReadList(bwpGrpIndex,0);
    if (bwpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpReadList returned %d when %d was expected",bwpIndex,0);
        return false;
    }

    bwpIndex = bwpIndexNext;
    svcBwpCfg_t svcBwpCfg,svcBwpCfgRd;
    retVal = svcBwpCreate(0, bwpIndex, &svcBwpCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcBwpCreate(bwpGrpIndex, 0, &svcBwpCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcBwpCreate(bwpGrpIndex, bwpIndex, NULL);
    if (retVal != -1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpCreate returned %d when %d was expected",retVal,-1);
        return false;
    }

    retVal = svcBwpCreate(bwpGrpIndex, bwpIndex, &svcBwpCfg);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpCreate returned %d when %d was expected",retVal,2);
        return false;
    }

    // Try to re-create BWP
    retVal = svcBwpCreate(bwpGrpIndex, bwpIndex, &svcBwpCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcBwpDelete(0, bwpIndex);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpDelete returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcBwpDelete(bwpGrpIndex, 0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpDelete returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcBwpDelete(bwpGrpIndex, bwpIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpDelete returned %d when %d was expected",retVal,3);
        return false;
    }

    for (k = 0;k < MAX_NUM_BWP; k++)
    {
        retVal = svcBwpCreate(bwpGrpIndex, k+1, &svcBwpCfg);
        if (retVal != 2)
        {
            DO_LOG_DEBUG(log_handle, "svcBwpCreate returned %d when %d was expected",retVal,2);
            return false;
        }
    }

    // Try to create one more than there is resources for...
    retVal = svcBwpCreate(bwpGrpIndex, MAX_NUM_BWP+1, &svcBwpCfg);
    if (retVal != -2)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpCreate returned %d when %d was expected",retVal,-2);
        return false;
    }

    for (k = 0;k < MAX_NUM_BWP; k++)
    {
        retVal = svcBwpDelete(bwpGrpIndex, k+1);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcBwpCreate returned %d when %d was expected",retVal,3);
            return false;
        }
    }

    svcBwpCfg.cir = 1000;
    svcBwpCfg.eir = 2000;
    svcBwpCfg.cbs = 1001;
    svcBwpCfg.ebs = 2001;
    svcBwpCfg.cosIndex = 0;
    svcBwpCfg.cf = couplingYellowEirPlusCir;
    svcBwpCfg.cm = colorAware;
    bwpIndex = 1;
    retVal = svcBwpCreate(bwpGrpIndex, bwpIndex, &svcBwpCfg);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpCreate returned %d when %d was expected",retVal,2);
        return false;
    }

    //---------------------------------------- svcBwpRead
    retVal = svcBwpRead(bwpGrpIndex, bwpIndex, &svcBwpCfgRd);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpCreate returned %d when %d was expected",retVal,2);
        return false;
    }
    // check what was read back...
    if (memcmp(&svcBwpCfg,&svcBwpCfgRd,sizeof(svcBwpCfg)) !=0)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpRead did not read what what was written");
        return false;
    }
    //---------------------
    retVal = svcBwpWrite(0, bwpIndex,bwpParam_cosIndex,&svcBwpCfg.cosIndex);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpWrite returned %d when %d was expected",retVal,4);
        return false;
    }

    retVal = svcBwpWrite(bwpGrpIndex, 0,bwpParam_cosIndex,&svcBwpCfg.cosIndex);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpWrite returned %d when %d was expected",retVal,4);
        return false;
    }

    retVal = svcBwpWrite(bwpGrpIndex, bwpIndex,10,&svcBwpCfg.cosIndex);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpWrite returned %d when %d was expected",retVal,4);
        return false;
    }

    svcBwpCfg.cosIndex = 5;
    retVal = svcBwpWrite(bwpGrpIndex, bwpIndex,bwpParam_cosIndex,&svcBwpCfg.cosIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpWrite returned %d when %d was expected",retVal,3);
        return false;
    }

    svcBwpCfg.cosIndex = 0;
    retVal = svcBwpWrite(bwpGrpIndex, bwpIndex,bwpParam_cosIndex,&svcBwpCfg.cosIndex);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpWrite returned %d when %d was expected",retVal,4);
        return false;
    }
    // --------------------
    retVal = svcBwpGrpDelete(bwpGrpIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpDelete returned %d when %d was expected",retVal,3);
        return false;
    }

    bwpGrpIndex = svcBwpGrpReadList(0);
    if (bwpGrpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcBwpGrpReadList returned %d when %d was expected",bwpGrpIndex,0);
        return false;
    }

    return true;
}

bool basic_l2cpTest(void)
{
    l2cpGrpIndex_t	l2cpGrpIndex,l2cpGrpIndexNext;
    int		retVal;
    int k;

    l2cpGrpIndexNext	= svcL2cpGrpGetNextIndex();
    if (l2cpGrpIndexNext != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpGetNextIndex returned %d when %d was expected",l2cpGrpIndexNext,1);
        return false;
    }

    l2cpGrpIndex = svcL2cpGrpReadList(0);
    if (l2cpGrpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpReadList returned %d when %d was expected",l2cpGrpIndex,0);
        return false;
    }

    retVal = svcL2cpGrpCreate(0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcL2cpGrpCreate(l2cpGrpIndexNext);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpCreate returned %d when %d was expected",retVal,2);
        return false;
    }

    // attempt to re-create the same BWP Group
    retVal = svcL2cpGrpCreate(l2cpGrpIndexNext);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    l2cpGrpIndex = svcL2cpGrpReadList(0);
    if (l2cpGrpIndex != l2cpGrpIndexNext)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpReadList returned %d when %d was expected",l2cpGrpIndex,l2cpGrpIndexNext);
        return false;
    }

    retVal = svcL2cpGrpDelete(0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpDelete returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcL2cpGrpDelete(l2cpGrpIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpDelete returned %d when %d was expected",retVal,3);
        return false;
    }

    l2cpGrpIndex = 1;
    retVal = svcL2cpGrpCreate(l2cpGrpIndex);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpCreate returned %d when %d was expected",retVal,2);
        return false;
    }

    l2cpIndex_t	l2cpIndex,l2cpIndexNext;
    l2cpGrpIndex = 1;
    l2cpIndex =	svcL2cpGetNextL2cpIndex(0);
    if (l2cpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGetNextL2cpIndex returned %d when %d was expected",l2cpIndex,0);
        return false;
    }

    l2cpIndexNext =	svcL2cpGetNextL2cpIndex(l2cpGrpIndex);
    if (l2cpIndexNext != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGetNextL2cpIndex returned %d when %d was expected",l2cpIndexNext,1);
        return false;
    }

    l2cpIndex = svcL2cpReadList(0,0);
    if (l2cpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpReadList returned %d when %d was expected",l2cpIndex,0);
        return false;
    }

    l2cpIndex = svcL2cpReadList(l2cpGrpIndex,0);
    if (l2cpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpReadList returned %d when %d was expected",l2cpIndex,0);
        return false;
    }

    l2cpIndex = l2cpIndexNext;
    svcL2cpCfg_t svcL2cpCfg,svcL2cpCfgRd;
    retVal = svcL2cpCreate(0, l2cpIndex, &svcL2cpCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcL2cpCreate(l2cpGrpIndex, 0, &svcL2cpCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcL2cpCreate(l2cpGrpIndex, l2cpIndex, NULL);
    if (retVal != -1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpCreate returned %d when %d was expected",retVal,-1);
        return false;
    }

    svcL2cpCfg.l2cpType = l2cp_tunnel;
    svcL2cpCfg.matchScope = destinationAddressOnly;
    retVal = svcL2cpCreate(l2cpGrpIndex, l2cpIndex, &svcL2cpCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpCreate returned %d when %d was expected",retVal,2);
        return false;
    }

    // Try to re-create L2CP
    retVal = svcL2cpCreate(l2cpGrpIndex, l2cpIndex, &svcL2cpCfg);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpCreate returned %d when %d was expected",retVal,1);
        return false;
    }

    retVal = svcL2cpDelete(0, l2cpIndex);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpDelete returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcL2cpDelete(l2cpGrpIndex, 0);
    if (retVal != 1)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpDelete returned %d when %d was expected",retVal,1);
        return false;
    }
    retVal = svcL2cpDelete(l2cpGrpIndex, l2cpIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpDelete returned %d when %d was expected",retVal,3);
        return false;
    }

    for (k = 0;k < MAX_NUM_L2CP; k++)
    {
        retVal = svcL2cpCreate(l2cpGrpIndex, k+1, &svcL2cpCfg);
        if (retVal != 4)
        {
            DO_LOG_DEBUG(log_handle, "svcL2cpCreate returned %d when %d was expected",retVal,4);
            return false;
        }
    }

    // Try to create one more than there is resources for...
    retVal = svcL2cpCreate(l2cpGrpIndex, MAX_NUM_L2CP+1, &svcL2cpCfg);
    if (retVal != -2)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpCreate returned %d when %d was expected",retVal,-2);
        return false;
    }

    for (k = 0;k < MAX_NUM_L2CP; k++)
    {
        retVal = svcL2cpDelete(l2cpGrpIndex, k+1);
        if (retVal != 3)
        {
            DO_LOG_DEBUG(log_handle, "svcL2cpCreate returned %d when %d was expected",retVal,3);
            return false;
        }
    }

    svcL2cpCfg.l2cpType = l2cp_tunnel;
    memset(svcL2cpCfg.macAddress,0,6);
    svcL2cpCfg.matchScope = destinationAddressOnly;
    svcL2cpCfg.protocol = 2001;
    svcL2cpCfg.subType = 0;
    l2cpIndex = 1;
    retVal = svcL2cpCreate(l2cpGrpIndex, l2cpIndex, &svcL2cpCfg);
    if (retVal != 4)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpCreate returned %d when %d was expected",retVal,4);
        return false;
    }

    //---------------------------------------- svcL2cpRead
    retVal = svcL2cpRead(l2cpGrpIndex, l2cpIndex, &svcL2cpCfgRd);
    if (retVal != 2)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpCreate returned %d when %d was expected",retVal,2);
        return false;
    }
    // check what was read back...
    if (memcmp(&svcL2cpCfg,&svcL2cpCfgRd,sizeof(svcL2cpCfg)) !=0)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpRead did not read what what was written");
        return false;
    }
    // --------------------
    retVal = svcL2cpGrpDelete(l2cpGrpIndex);
    if (retVal != 3)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpDelete returned %d when %d was expected",retVal,3);
        return false;
    }

    l2cpGrpIndex = svcL2cpGrpReadList(0);
    if (l2cpGrpIndex != 0)
    {
        DO_LOG_DEBUG(log_handle, "svcL2cpGrpReadList returned %d when %d was expected",l2cpGrpIndex,0);
        return false;
    }

    return true;
}

bool runUniTests(void)
{
    bool overAllResult = true;

#if 0
    if (!basic_cosTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic Service COS - Test Failed.");
        overAllResult = false;
    }
    else
    {
        DO_LOG_DEBUG(log_handle, "Basic Service COS - Test Passed.");
    }
#endif

#if 0
    if (!basic_bwpTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic Service BWP - Test Failed.");
        overAllResult = false;
    }
    else
    {
        DO_LOG_DEBUG(log_handle, "Basic Service BWP - Test Passed.");
    }
#endif

#if 1
    if (!basic_l2cpTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic Service L2CP - Test Failed.");
        overAllResult = false;
    }
    else
    {
        DO_LOG_DEBUG(log_handle, "Basic Service L2CP - Test Passed.");
    }
#endif
#if 0
    if (!basic_interfaceTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic Service Interface - Test Failed.");
        overAllResult = false;
    }
    else
    {
        DO_LOG_DEBUG(log_handle, "Basic Service Interface - Test Passed.");
    }
#endif

#if 0
    if (!basic_uniTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic Service UNI - Test Failed.");
        overAllResult = false;
    }
    else
    {
        DO_LOG_DEBUG(log_handle, "Basic Service UNI - Test Passed.");
    }
#endif

#if 0
    if (!basic_evcTest())
    {
        DO_LOG_DEBUG(log_handle, "Basic Service EVC - Test Failed.");
        overAllResult = false;
    }
    else
    {
        DO_LOG_DEBUG(log_handle, "Basic Service EVC - Test Passed.");
    }
#endif

    if (overAllResult == false)
    {
        DO_LOG_ERROR(log_handle, "***********************");
        DO_LOG_ERROR(log_handle, "One or more Service UNI Test Failed");
        DO_LOG_ERROR(log_handle, "***********************");
    }
    else
    {
        DO_LOG_DEBUG(log_handle, "++++++++++++++++++++++++++");
        DO_LOG_DEBUG(log_handle, " WAHOO!! All Service UNI tests Passed");
        DO_LOG_DEBUG(log_handle, "++++++++++++++++++++++++++");
    }
    return (overAllResult);
}

void runAllTests(void)
{
    int retVal;
#if 1
    runCFMTests();
#endif
#if 0
    runUniTests();
#endif

    testStatus_t testStatus;
#if 0

    rfc2544Cfg_t rfc2544Cfg;
    rfc2544Results_t rfc2544Results;

    retVal = rfc2544Read(&testStatus, &rfc2544Cfg, &rfc2544Results);
    retVal = rfc2544Stop();

    rfc2544Cfg.targetIsMep = true;
    rfc2544Cfg.targetMep.mdIndex = 37;
    rfc2544Cfg.targetMep.maIndex = 1;
    rfc2544Cfg.targetMep.lMepId = 10;
    rfc2544Cfg.targetMep.rMepId = 20;
    rfc2544Cfg.targetMep.prio = 5;

    rfc2544Cfg.enThroughput = true;
    rfc2544Cfg.throughPutCfg.acceptedFrameLoss = 0;
    rfc2544Cfg.throughPutCfg.maxRate = 5000;
    rfc2544Cfg.throughPutCfg.minRate = 1000;
    rfc2544Cfg.throughPutCfg.frameSizeList[0] = 256;
    rfc2544Cfg.throughPutCfg.trialDuration  = 6;

    retVal = rfc2544Configure(&rfc2544Cfg);
    if (retVal != 4)
    {
        DO_LOG_ERROR(log_handle,"rfc2544Configure failed, returned %d",retVal);
        return;
    }

    retVal = rfc2544Start();
#endif


    y1564Cfg_t y1564Cfg;
    y1564SelResults_t	y1564Results;

    retVal = y1564Read(&testStatus, &y1564Cfg, 0, sel_configuration, &y1564Results);
    retVal = y1564Stop();
#if 0
    y1564Cfg.enConfigTest = true;
    y1564Cfg.configStepDuration = 6;
    y1564Cfg.performanceDuration = 1;

    y1564Cfg.serviceCfg[0].enable = true;
    y1564Cfg.serviceCfg[0].targetIsMep = true;
    y1564Cfg.serviceCfg[0].targetMep.mdIndex = 37;
    y1564Cfg.serviceCfg[0].targetMep.maIndex = 1;
    y1564Cfg.serviceCfg[0].targetMep.lMepId = 10;
    y1564Cfg.serviceCfg[0].targetMep.rMepId = 20;
    y1564Cfg.serviceCfg[0].targetMep.prio = 4;
    y1564Cfg.serviceCfg[0].targetMep.overwritePCP = true;
    y1564Cfg.serviceCfg[0].cir = 5;
    y1564Cfg.serviceCfg[0].eir = 1;

    retVal = y1564Configure(&y1564Cfg);
    if (retVal != 4)
    {
        DO_LOG_ERROR(log_handle,"y1564Configure failed, returned %d",retVal);
        return;
    }

    retVal = y1564Start();
#endif
}

void ccm_task(void* param)
{
    int                 retVal;
    mdMibInfo_t         mdMibInfo;
    networkAddress_t    faultAlarmNetAddr;
    uint16_t            vLanList[5] = {0,0,0,0,0};

    //ts_printf("Waiting for 20Sec.");
    osSleepMS(5000);
#ifdef DEBUG_PRINT_L1
    ts_printf("Local MEP creation - In progress...\r\n");
#endif

    if (!basic_createMepTest(false))
    {
        ts_printf("||||||||||Basic Local MEP creation - Test Failed.");
    }
    else
    {
#ifdef DEBUG_PRINT_L1
        ts_printf("Local MEP creation - Completed successfully.");
#endif
    }
    while(1)
    {

    }
}


void startCCMTestProcess(void)
{
       osTaskCreate(ccm_task, ( signed char * ) "Test Task", 1024, NULL, tskIDLE_PRIORITY+4, NULL);

}
