1.3.2.2 Using the G3 MAC Wrapper Module

The G3 MAC Wrapper module is located below the G3 Adaptation layer and on top of both PLC and RF MAC layers. Its mission is to provide abstraction to upper layer (being G3 Adaptation layer or an application running on top of G3 MAC), to the fact that we are working on a PLC node, an RF node, or a Hybrid (PLC & RF) node.
Figure . MAC Wrapper Unified Access
mac_wrapper_unified_access

Example application to send data from a G3 node at MAC level, and wait for a response

#define SRC_PANID      0X1234
#define SRC_ADDRESS    0x0001
#define DEST_PANID     0X1234
#define DEST_ADDRESS   0x0002

SYS_MODULE_OBJ sysObjMacWrp;
MAC_WRP_HANDLE g3handle;
APP_G3_MAC_DATA appG3Mac;
bool txConfirmed;
bool frameReceived;
uint8_t txHandle;
uint8_t txBuffer[MAC_MAX_PAYLOAD_SIZE];
uint16_t txLength;

static void APP_SendData(uint8_t* pData, uint16_t length)
{
    MAC_WRP_DATA_REQUEST_PARAMS drParams;

    if (length > MAC_MAX_PAYLOAD_SIZE) {
        return;
    }

    /* Prepare Data Request parameters */
    drParams.srcAddressMode = MAC_WRP_ADDRESS_MODE_SHORT;
    drParams.destPanId = DEST_PANID;
    drParams.destAddress = DEST_ADDRESS;
    drParams.msduLength = length;
    drParams.msdu = pData;
    drParams.msduHandle = txHandle++;
    drParams.txOptions = 1;
    drParams.securityLevel = MAC_WRP_SECURITY_LEVEL_ENC_MIC_32;
    drParams.keyIndex = 0;
    drParams.qualityOfService = MAC_WRP_QUALITY_OF_SERVICE_NORMAL_PRIORITY;
    drParams.mediaType = MAC_WRP_MEDIA_TYPE_REQ_PLC_BACKUP_RF;

    /* Send MAC Frame */
    txConfirmed = false;
    MAC_WRP_DataRequest(g3handle, &drParams);
}

static void APP_G3_MAC_DATACfmCb(MAC_WRP_DATA_CONFIRM_PARAMS *cfmObj)
{
    /* Update flag */
    txConfirmed = true;
}

static void APP_G3_MAC_DATAIndCb(MAC_WRP_DATA_INDICATION_PARAMS *indObj)
{
    /* Do whatever with received frame */
    frameReceived = true;
}

void APP_G3_MAC_Initialize(void)
{
    /* Call system-like Initialize function */
    sysObjMacWrp = MAC_WRP_Initialize(MAC_WRP_INDEX_0);

    /* Set App state */
    appG3Mac.state = APP_G3_MAC_STATE_IDLE;
}

void APP_G3_MAC_OpenAndInit(void)
{
    /* Configure callbacks */
    MAC_WRP_HANDLERS macWrpHandlers = {
        .dataConfirmCallback = APP_G3_MAC_DATACfmCb,
        .dataIndicationCallback = APP_G3_MAC_DATAIndCb,
        .resetConfirmCallback = NULL, // Reset primitive not used
        .beaconNotifyIndicationCallback = NULL, // BCN notify primitive not used
        .scanConfirmCallback = NULL, // Scan primitive not used
        .startConfirmCallback = NULL, // Start primitive not used
        .commStatusIndicationCallback = NULL, // CommStatus primitive not used
        .snifferIndicationCallback = NULL, // MAC Sniffer not used
    };

    /* Open an instance of module */
    g3handle = MAC_WRP_Open(MAC_WRP_INDEX_0, MAC_WRP_BAND_CENELEC_A);
    /* Set callbacks */
    MAC_WRP_SetCallbacks(g3handle, &macWrpHandlers);
}

void APP_G3_MAC_Tasks(void)
{
    /* Check the application's current state. */
    switch (appG3Mac.state)
    {
        case APP_STATE_IDLE:
        {
            /* Go to next state */
            appG3Mac.state = APP_G3_MAC_STATE_OPEN_AND_INIT;
        }
        break;

        case APP_G3_MAC_STATE_OPEN_AND_INIT:
        {
            /* Open and Init a MAC Wrapper instance */
            APP_G3_MAC_OpenAndInit();
            appG3Mac.state = APP_G3_MAC_STATE_SET_PARAMS;
        }
        break;

        case APP_G3_MAC_STATE_SET_PARAMS:
        {
            /* Set own Address and PAN_ID */
            MAC_WRP_STATUS status;
            MAC_WRP_PIB_VALUE pibVal;
            uint16_t panId = SRC_PANID;
            uint16_t address = SRC_ADDRESS;

            pibVal.length = 2;
            memcpy(pibVal.value, &panId, sizeof(panId));
            status = MAC_WRP_SetRequestSync(g3handle, MAC_WRP_PIB_PAN_ID, 0, &pibVal);
            if (status == MAC_WRP_STATUS_SUCCESS)
            {
                memcpy(pibVal.value, &address, sizeof(address));
                status = MAC_WRP_SetRequestSync(g3handle, MAC_WRP_PIB_SHORT_ADDRESS, 0, &pibVal);
                if (status == MAC_WRP_STATUS_SUCCESS)
                {
                    /* Go to next state */
                    appG3Mac.state = APP_G3_MAC_STATE_TX_REQUEST;
                }
            }
            break;
        }

        case APP_G3_MAC_STATE_TX_REQUEST:
        {
            /* Build a frame in buffer and set length before calling SendData */
            APP_SendData(txBuffer, txLength);
            appG3Mac.state = APP_G3_MAC_STATE_WAITING_TX_CFM;
            break;
        }

        case APP_G3_MAC_STATE_WAITING_TX_CFM:
        {
            if (txConfirmed)
            {
                frameReceived = false;
                appG3Mac.state = APP_G3_MAC_STATE_WAITING;
            }
            break;
        }

        case APP_G3_MAC_STATE_WAITING:
        {
            if (frameReceived)
            {
                frameReceived = false;
                /* Send another frame */
                appG3Mac.state = APP_G3_MAC_STATE_TX_REQUEST;
            }
            break;
        }

        /* The default state should never be executed. */
        default:
        {
            /* Handle error in application's state machine. */
            break;
        }
    }
}