tZGVoidReturn ZGLibConfirm(tZGU8 type) { if ( ZGLibQDelete(type) == kZGFailure ) { ZGErrorHandler((ROM FAR char *) "ZGLibConfirm Error"); } ZGSetRawRxMgmtInProgress(kZGBoolFalse); }
static tZGReturnStatus ZGLibQAdd( tZGU16 mgmt_len, tZGU8 mgmt_type, tZGU8 mgmt_info, tDispatchRequest appRequestHandler, tDispatchComplete appCompleteHandler, tZGVoidInput *appOpaquePtr) { tZGReturnStatus retCode = kZGFailure; /* space available ? */ if ( gConsumed+1 > ZG_LIB_MGMT_Q_SIZE ) return retCode; if ( appCompleteHandler == kNULL ) ZGErrorHandler("Complete Missing"); gLibQ[gHead].completeCallback = appCompleteHandler; gLibQ[gHead].opaquePtr = appOpaquePtr; gLibQ[gHead].len = mgmt_len; gLibQ[gHead].type = mgmt_type; gLibQ[gHead].info = mgmt_info; gLibQ[gHead].reqLen = 0; /* immediately call the user callback to fill out it's request data structure */ if ( appRequestHandler != kNULL ) gLibQ[gHead].reqLen = DISPATCH_REQUEST( appRequestHandler, &gLibQ[gHead].request, appOpaquePtr ); else if ( mgmt_type != kZGMSGGetParam ) ZGErrorHandler("Request Missing\n\r"); retCode = SendManagementMsg( gLibQ[gHead].request, gLibQ[gHead].len, gLibQ[gHead].type, gLibQ[gHead].info ); gHead++; if(gHead >= ZG_LIB_MGMT_Q_SIZE) gHead = 0; gConsumed++; return retCode; }
tZGVoidReturn ZGLibConfirm(tZGU8 type, tZGDataPtr fourByteHeader, tZGDataPtr pBuf, tZGU16 len) { if ( ZGLibQDelete(type, fourByteHeader, pBuf, len) == kZGFailure ) { ZGErrorHandler("ZGLibConfirm Error"); } if ( pBuf != NULL) { ZGSYS_READBUF_CLEAN(pBuf); len = 0; } }
static tZGReturnStatus ZGLibQDelete( tZGU8 cfrm_type, tZGDataPtr cfrm_fourByteHeader, tZGDataPtr cfrm_pBuf, tZGU16 cfrm_len) { if ( gConsumed == 0 ) ZGErrorHandler("Unknown complete callback"); DISPATCH_COMPLETE( gLibQ[gTail].completeCallback, cfrm_type, cfrm_fourByteHeader, cfrm_pBuf, cfrm_len, gLibQ[gTail].opaquePtr ); gTail++; if(gTail >= ZG_LIB_MGMT_Q_SIZE) gTail = 0; gConsumed--; return kZGSuccess; }
tZGVoidReturn ZGLinkMgrSetMode( tZGLMNetworkMode mode ) { APPCXT.FSM.currentMode = mode; switch ( mode ) { case kZGLMNetworkModeIdle: APPCXT.FSMSelector = g_emptyFSM; break; #if !defined (ZG_CONFIG_NO_WIFIMGRII) case kZGLMNetworkModeInfrastructure: APPCXT.FSMSelector = g_mangedFSM; break; #endif #if !defined (ZG_CONFIG_NO_ADHOCMGRII) case kZGLMNetworkModeAdhoc: APPCXT.FSMSelector = g_adhocFSM; break; #endif /* ADHOC MODE */ default: ZGErrorHandler((ROM FAR char*) "BAD MODE"); } APPCXT.FSM.stateStatus = kSUCCESS; APPCXT.FSM.currentState = kSTIdle; APPCXT.bRetryBSSConnect = kZGBoolTrue; APPCXT.nJoinRetryState = 0; APPCXT.nRetryBSSConnect = 0; APPCXT.nAssocRetryState = 0; APPCXT.nAuthRetryState = 0; APPCXT.nScanRetryState = 0; }
/***************************************************************************** * FUNCTION: ZGPrvComStateMachine * * RETURNS: N/A * * PARAMS: * N/A * * * NOTES: Represents the State machine for the COM layer of the ZG Driver. * The responsibility of the COM layer is to schedule SPI operations * and act as a receiver of interrupt notifications from the G2100. * Essentially read and write fifo operations are submitted from the * MAC layer 1 at a time and separately an interrupt can be received * from the G2100 the meaning of which needs to be determined. The * State machine initially starts in the idle state and waits for one * of these 2 events with priority going to the interrupt event however * once an operation is started in cannot be pre-empted. Interrupt * processing requires reading and writing several chip registers to * learn the meaning of the interrupt and clear the interrupt. With * the results being routed to the MAC layer for further processing. * Fifo operation is either a read or write operation which involves * several SPI steps that must be scheduled *****************************************************************************/ tZGVoidReturn ZGPrvComStateMachine(tZGVoidInput) { tZGU8 bLoop = 0; tZGU16 len; tZGBool res; do { if(COMCXT.state == kComStIdle) { //----------------------------------------- // if there is an EINT interrupt to process //----------------------------------------- if(COMCXT.bIntServiceReq == kZGBoolTrue) { COMCXT.bIntServiceReq = kZGBoolFalse; COMCXT.state = kComStIntService; } //-------------------------------------------- // if there is management msg to read or write //-------------------------------------------- else if(COMCXT.bRdWtReady == kZGBoolTrue) { /* if the chip is in low power mode then it must first be * brought out of low power before attempting a write * operation. */ if(COMCXT.bLowPowerModeActive) { ChangeLowPowerMode(kZGBoolFalse); } COMCXT.state = (RWCXT.dir == kZGDirWrite)? kComStWriteOperation : kComStReadOperation; //---------------------------- // if doing a management write //---------------------------- if (RWCXT.dir == kZGDirWrite) { res = ZGSendRAWManagementFrame(RWCXT.len); if (res == kZGBoolFalse) { ZGErrorHandler((ROM char *)"Mgmt Send Failed"); } COMCXT.bRdWtReady = kZGBoolFalse; ZGPrvMacOpComplete(); COMCXT.state = kComStIdle; } //----------------------------- // else doing a management read //----------------------------- else { // if the Raw Rx buffer is available, or only has the scratch mounted, then mount it so // we can process received Mgmt message. Otherwise, stay in this state and keep checking // until we can mount the Raw Rx buffer and get the management message. Once the Raw Rx // is acquired, rx data packets are held off until we finish processing mgmt message. if ( ZGRawGetMgmtRxBuffer(&len) ) { // handle received managment message COMCXT.bRdWtReady = kZGBoolFalse; ZGPrvMacOpComplete(); COMCXT.state = kComStIdle; // reenable interrupts zgHALEintEnable(); } } } //------------------------------------------------------------- // else no manangement tx or rx to do, so check for other stuff //------------------------------------------------------------- else { bLoop = 0; /* manage low power control of g2100 */ if(COMCXT.bLowPowerModeDesired == kZGBoolTrue && COMCXT.bLowPowerModeActive == kZGBoolFalse && MACCXT.bMgmtTxMsgReady == kZGBoolTrue) { ChangeLowPowerMode(kZGBoolTrue); } } } //-------------------------- // else COMCXT.state != IDLE //-------------------------- else { bLoop = 1; switch(COMCXT.state) { case kComStIntService: /* use spi to determine device interrupt reason */ ProcessInterruptServiceResult(); break; case kComStReadOperation: /* spi fifo read operation in progress */ COMCXT.state = kComStReadWaitFifoDone; ZGPrvMacOpComplete(); break; case kComStWriteOperation: /* spi fifo write operation in progress */ COMCXT.state = kComStWriteWaitFifoDone; ZGPrvMacOpComplete(); break; case kComStReadWaitFifoDone: COMCXT.state = kComStIdle; break; case kComStWriteWaitFifoDone: /* complete the fifo operation */ COMCXT.state = kComStIdle; break; } } } while(bLoop); }
static tZGVoidReturn ProcessInterruptServiceResult(tZGVoidInput) { //tZGU16 numBytes; tZGU8 hostIntRegValue; tZGU8 hostIntMaskRegValue; tZGU8 hostInt; /* read hostInt register and hostIntMask register to determine cause of interrupt */ hostIntRegValue = Read8BitZGRegister(kZGCOMRegHostInt); // or in the saved interrupts during the time when we were waiting for raw complete, set by zgDriverEintHandler() hostIntRegValue |= hostIntSaved; // done with the saved interrupts, clear variable hostIntSaved = 0; hostIntMaskRegValue = Read8BitZGRegister(kZGCOMRegHostIntMask); // AND the two registers together to determine which active, enabled interrupt has occurred hostInt = hostIntRegValue & hostIntMaskRegValue; // if received a level 2 interrupt if((hostInt & kZGCOMRegHostIntMaskInt2) == kZGCOMRegHostIntMaskInt2) { /* read the 16 bit interrupt register */ /* CURRENTLY unhandled interrupt */ ZGErrorHandler((ROM char *)"16-bit Interrupt in COM"); COMCXT.state = kComStIdle; zgHALEintEnable(); } // else if got a FIFO 1 Threshold interrupt (Management Fifo) else if((hostInt & kZGCOMRegHostIntMaskFifo1Thresh) == kZGCOMRegHostIntMaskFifo1Thresh) { /* clear this interrupt */ Write8BitZGRegister(kZGCOMRegHostInt, kZGCOMRegHostIntMaskFifo1Thresh); // notify MAC state machine that management message needs to be processed ZGPrvMacReadReady(); COMCXT.state = kComStIdle; } // else if got a FIFO 0 Threshold Interrupt (Data Fifo) else if((hostInt & kZGCOMRegHostIntMaskFifo0Thresh) == kZGCOMRegHostIntMaskFifo0Thresh) { /* clear this interrupt */ Write8BitZGRegister(kZGCOMRegHostInt, kZGCOMRegHostIntMaskFifo0Thresh); gHostRAWDataPacketReceived = true; /* this global flag is used in MACGetHeader() to determine a received data packet */ COMCXT.state = kComStIdle; /* if the chip is in low power mode then it must first be * brought out of low power before attempting a write * operation. */ if(COMCXT.bLowPowerModeActive) { ChangeLowPowerMode(kZGBoolFalse); } } // else got a Host interrupt that we don't handle else if(hostInt) { /* unhandled interrupt */ COMCXT.state = kComStIdle; /* clear this interrupt */ Write8BitZGRegister(kZGCOMRegHostInt, hostInt); zgHALEintEnable(); } // we got a spurious interrupt (no bits set in register) else { /* spurious interrupt */ COMCXT.state = kComStIdle; zgHALEintEnable(); } }
void ZGLinkMgr(void) { tDispatchZGLib appLibFuncPtr = kNULL; tDispatchComplete appCompleteHandler = kNULL; tDispatchRequest appRequestHandler = kNULL; tDispatchNext appNextStateHandler = APPCXT.FSMSelector[APPCXT.FSM.currentState].next_state_func; enum tFSMValidStates tempNext = kNULL; /* This is an optional runtime override to the static pass/fail next states in a FSM table */ /* The next state is useful when the decission process for a next state is based on random user input */ /* or there are multiple edges to the next state in the FSM graph */ if ( appNextStateHandler != kNULL ) { /* If the nextState handler returns null, it does not want to override */ tempNext = DISPATCH_NEXT(appNextStateHandler); } switch ( APPCXT.FSM.stateStatus ) { case kSUCCESS: /* Does the next state hander have a runtime overide? of the static pass entry */ if ( tempNext != kNULL ) APPCXT.FSM.currentState = tempNext; else APPCXT.FSM.currentState = APPCXT.FSMSelector[ APPCXT.FSM.currentState ].next_success; break; case kFAILURE: /* Does the next state hander have a runtime overide? of the static fail entry */ if ( tempNext != kNULL ) APPCXT.FSM.currentState = tempNext; else /* The pass or fail next states are defined in FSM tables */ APPCXT.FSM.currentState = APPCXT.FSMSelector[ APPCXT.FSM.currentState ].next_fail; break; case kRETRY: /* call the same state again */ break; case kPENDING: /* wait for driver to complete call*/ return; default: ZGErrorHandler((ROM FAR char*) "Unknown FSM status"); break; } appLibFuncPtr = APPCXT.FSMSelector[APPCXT.FSM.currentState].zg_library_func; if ( appLibFuncPtr != kNULL ) { /* iniate the call to the ZeroG library */ appCompleteHandler = APPCXT.FSMSelector[APPCXT.FSM.currentState].complete_func; appRequestHandler = APPCXT.FSMSelector[APPCXT.FSM.currentState].request_func; g_linkMgrCtx.FSM.stateStatus = kPENDING; /* This call can fail, if another library call has been made or there is no memory for a new call */ if ( DISPATCH_ZGLIB (appLibFuncPtr, appRequestHandler, appCompleteHandler, kNULL) != kZGSuccess ) { g_linkMgrCtx.FSM.stateStatus = kRETRY; } } } /* end switch */
/***************************************************************************** * FUNCTION: do_iwpriv_cmd * * RETURNS: None * * PARAMS: None * * NOTES: Responds to the user invoking ifconfig *****************************************************************************/ tZGVoidReturn do_iwpriv_cmd(tZGVoidInput) { tZGU8 i; tZGU8 temp; tZGBool cont_parse; tZGS8* ptrString; gLineParseState = kZGWaitingForParamKeyword; // if user only typed in iwpriv with no other parameters if (ARGC == 1u) { IwprivDisplayStatus(); } // else loop through each parameter else { // parse each param and set state variables for (i = 1; i < ARGC; ++i) { switch (gLineParseState) { case kZGWaitingForParamKeyword: if ( !getParam(i) ) { return; } break; case kZGWaitingForWpaPsk: /* Can only set security in idle state */ if ( ZG_IS_CONNECTED() == kZGBoolTrue ) { ZG_PUTRSUART("Security context may only be set in idle state\n\r"); return; } /* The ARGV buffer is modified in place */ if ( !ExtractandValidateWpaPSK( ARGV[i] ) ) { ZG_PUTRSUART("WPA PSK must be exactly 64 bytes\n\r"); return; } ZG_SET_WPAPSK( (tZGU8Ptr) ARGV[i] ); gLineParseState = kZGWaitingForParamKeyword; break; case kZGWaitingForWpaStr: /* Can only set security in idle state */ if ( ZG_IS_CONNECTED() == kZGBoolTrue ) { ZG_PUTRSUART("Security context may only be set in idle state\n\r"); return; } ptrString = ARGV[i++]; /* if the start char is found, gobble that char */ if ( (cont_parse = ExtractWpaStrStart(ptrString)) == kZGBoolTrue) { ptrString++; } /* this code concats tokens together with whitespace */ /* until no more tokens or the EOS " char is found */ while ( cont_parse && (i++ < ARGC)) { cont_parse = ExtractWpaStrEnd( ptrString ); } /* if the EOS char is not found then cont parse is true */ if (cont_parse) { ZG_PUTRSUART("Passphrase missing EOS '\"' \n\r"); return; } /* temp contains the string length after call */ if ( !ValidateWpaStr(&ptrString, &temp) ) { ZG_PUTRSUART("Passphrase must be between 8 and 63 chars\n\r"); return; } ZG_SET_WPA_PASSPHRASE( ptrString, temp ); gLineParseState = kZGWaitingForParamKeyword; break; case kZGWaitingForEnc: /* Can only set security in idle state */ if ( ZG_IS_CONNECTED() == kZGBoolTrue ) { ZG_PUTRSUART("Security context may only be set in idle state\n\r"); return; } /* temp contains the encryption type enum */ if ( !ExtractandValidateEncType(ARGV[i], &temp) ) { ZG_PUTRSUART("Invalid encyption type\n\r"); return; } ZG_SET_ENC_TYPE( temp ); gLineParseState = kZGWaitingForParamKeyword; break; case kZGWaitingForWepAuth: /* Can only set security in idle state */ if ( ZG_IS_CONNECTED() == kZGBoolTrue ) { ZG_PUTRSUART("Security context may only be set in idle state\n\r"); return; } /* temp contains the Wep Auth type enum */ if ( !ExtractandValidateAuthType(ARGV[i], &temp) ) { ZG_PUTRSUART("Invalid WEP Auth type\n\r"); return; } ZG_SET_AUTH_TYPE( temp ); gLineParseState = kZGWaitingForParamKeyword; break; case kZGWaitingForWepKey: /* Can only set security in idle state */ if ( ZG_IS_CONNECTED() == kZGBoolTrue ) { ZG_PUTRSUART("Security context may only be set in idle state\n\r"); return; } /* temp contains the active WEP key index 1 of 4 */ if ( !ExtractandValidateWepIndex(ARGV[i], &temp) ) { ZG_PUTRSUART("Invalid WEP key index\n\r"); return; } /* check for a 3rd optional parameter */ if ( (i+1 < ARGC) && (getParamType(ARGV[i+1]) == kZGUnknownParam) ) { i++; /* advance to the optional param */ /* The ARGV buffer is modified in place */ if ( ExtractandValidateWepLong( ARGV[i] ) ) { ZG_SET_WEP_KEY_LONG( (tZGU8Ptr) ARGV[i], temp ); } else if ( ExtractandValidateWepShort( ARGV[i] ) ) { ZG_SET_WEP_KEY_SHORT( (tZGU8Ptr) ARGV[i], temp ); } else { ZG_PUTRSUART("\n\rWarning, 64/128bit WEP key format not valid \n\r\t"); return; } } ZG_SET_WEP_ACTIVE_INDEX(temp); gLineParseState = kZGWaitingForParamKeyword; break; default: ZGErrorHandler((ROM FAR char*)"iwpriv param"); break; } // end switch } // end for } switch (gLineParseState) { case kZGWaitingForBeacon: // Send an untampered frame that looks like a Beacon. iwpriv_beacon(); gLineParseState = kZGWaitingForParamKeyword; break; default: //do nothing break; } if (gLineParseState != (tZGU8)kZGWaitingForParamKeyword) { ZG_PUTRSUART("Missing value after last parameter\n\r"); } }
static void InitAppConfig(void) { AppConfig.Flags.bIsDHCPEnabled = TRUE; AppConfig.Flags.bInConfigMode = TRUE; memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr)); // { // _prog_addressT MACAddressAddress; // MACAddressAddress.next = 0x157F8; // _memcpy_p2d24((char*)&AppConfig.MyMACAddr, MACAddressAddress, sizeof(AppConfig.MyMACAddr)); // } AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul; AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val; AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul; AppConfig.DefaultMask.Val = AppConfig.MyMask.Val; AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul; AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul; AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul; // SNMP Community String configuration #if defined(STACK_USE_SNMP_SERVER) { BYTE i; static ROM char * ROM cReadCommunities[] = SNMP_READ_COMMUNITIES; static ROM char * ROM cWriteCommunities[] = SNMP_WRITE_COMMUNITIES; ROM char * strCommunity; for(i = 0; i < SNMP_MAX_COMMUNITY_SUPPORT; i++) { // Get a pointer to the next community string strCommunity = cReadCommunities[i]; if(i >= sizeof(cReadCommunities)/sizeof(cReadCommunities[0])) strCommunity = ""; // Ensure we don't buffer overflow. If your code gets stuck here, // it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h // is either too small or one of your community string lengths // (SNMP_READ_COMMUNITIES) are too large. Fix either. if(strlenpgm(strCommunity) >= sizeof(AppConfig.readCommunity[0])) while(1); // Copy string into AppConfig strcpypgm2ram((char*)AppConfig.readCommunity[i], strCommunity); // Get a pointer to the next community string strCommunity = cWriteCommunities[i]; if(i >= sizeof(cWriteCommunities)/sizeof(cWriteCommunities[0])) strCommunity = ""; // Ensure we don't buffer overflow. If your code gets stuck here, // it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h // is either too small or one of your community string lengths // (SNMP_WRITE_COMMUNITIES) are too large. Fix either. if(strlenpgm(strCommunity) >= sizeof(AppConfig.writeCommunity[0])) while(1); // Copy string into AppConfig strcpypgm2ram((char*)AppConfig.writeCommunity[i], strCommunity); } } #endif // Load the default NetBIOS Host Name memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 16); FormatNetBIOSName(AppConfig.NetBIOSName); #if defined(ZG_CS_TRIS) // Load the default SSID Name if (sizeof(MY_DEFAULT_SSID_NAME) > sizeof(AppConfig.MySSID)) { ZGErrorHandler((ROM char *)"AppConfig.MySSID[] too small"); } memcpypgm2ram(AppConfig.MySSID, (ROM void*)MY_DEFAULT_SSID_NAME, sizeof(MY_DEFAULT_SSID_NAME)); #endif #if defined(EEPROM_CS_TRIS) { BYTE c; // When a record is saved, first byte is written as 0x60 to indicate // that a valid record was saved. Note that older stack versions // used 0x57. This change has been made to so old EEPROM contents // will get overwritten. The AppConfig() structure has been changed, // resulting in parameter misalignment if still using old EEPROM // contents. // TCPIP configuration settings will be moved to start from 0x0050. // The first 80 bytes will be used for application settings. XEEReadArray(0x0000, &c, 1); if(c == 0x60u) XEEReadArray(0x0001, (BYTE*)&AppConfig, sizeof(AppConfig)); else SaveAppConfig(); } #elif defined(SPIFLASH_CS_TRIS) { BYTE c; SPIFlashReadArray(0x0000, &c, 1); if(c == 0x60u) SPIFlashReadArray(0x0001, (BYTE*)&AppConfig, sizeof(AppConfig)); else SaveAppConfig(); } #endif }
static tZGReturnStatus ZGLibQAdd( tZGU16 mgmt_len, tZGU8 mgmt_type, tZGU8 mgmt_info, tDispatchRequest appRequestHandler, tDispatchComplete appCompleteHandler, tZGVoidInput *appOpaquePtr) { tZGReturnStatus retCode = kZGFailure; /* space available ? */ if ( gPending ) { return retCode; } if ( appCompleteHandler == kNULL ) { ZGErrorHandler((ROM FAR char*)"No Completion Handler Provided"); } /* Make sure the RAW windown is ready & mounted */ if ( !ZGisTxMgmtReady() ) { return retCode; } gLibQ.completeCallback = appCompleteHandler; gLibQ.opaquePtr = appOpaquePtr; gLibQ.len = mgmt_len; gLibQ.type = mgmt_type; gLibQ.info = mgmt_info; gLibQ.reqLen = 0; /* immediately call the user callback to fill out it's request data structure */ if ( appRequestHandler != kNULL ) { memset( (void *) &gLibQ.request, 0, kLibMgrCxtBufLen); gLibQ.reqLen = DISPATCH_REQUEST( appRequestHandler, (void *) &gLibQ.request, (void *) appOpaquePtr ); } else if ( mgmt_type != kZGMSGGetParam ) { ZGErrorHandler((ROM FAR char*)"Request Handler Necessary for GetParam"); } /* Must block for the completion - there is only 1 TX RAW pipe, and any dataplane or other ctrl plane */ /* application can mess up mgmt this request transaction "in flight" with a new request */ if ( (retCode = ZGLibRAWSendMessage()) == kZGSuccess ) { gPending = kZGBoolTrue; do { ZGProcess(); // if received a data rx don't send a mgmt until data processed if (gHostRAWDataPacketReceived) { gHostRAWDataPacketReceived = kZGBoolFalse; /* Mount Read FIFO to RAW Rx window. Allows use of RAW engine to read rx data packet. */ /* Function call returns number of bytes in the data packet. */ ZGRawMove(kRxPipeRAW, kZGRawSrcDestCmdProcessor, true, 0); /* unmount the raw to free up receive packet and the RAW engine */ ZGRawMove(kRxPipeRAW, kZGRawSrcDestDataPool, false, 0); // ensure interrupts enabled zgHALEintEnable(); } } while ( gPending ); } return retCode; }