1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276 |
- /*
- This software is subject to the license described in the License.txt file
- included with this software distribution. You may not use this file except in compliance
- with this license.
- Copyright (c) Dynastream Innovations Inc. 2012
- All rights reserved.
- */
- #include "StdAfx.h"
- #include "ANTChannel.h"
- #include "ANTPlus.h"
- #include "ANTClass.h"
- /**************************************************************************
- * ANTChannel::ANTChannel
- *
- * ANT CHannel constructor - called for each channel allocated to a
- * device.
- *
- * Params:
- *
- * ucInstanceNum_: Corressponds to channel number.
- * ucSimType_: Type of simulator this channel will represent - either sensor or display.
- *
- * returns: N/A
- *
- **************************************************************************/
- ANTChannel::ANTChannel(UCHAR ucInstanceNum_, UCHAR ucSimType_, ANTPlatform eHWType_, CapabilitiesStruct sCapabilities_)
- {
- System::Windows::Forms::Control::CheckForIllegalCrossThreadCalls = FALSE;
- InitializeComponent();
- bTXPowerUIEnabled = FALSE;
- ucSimType = ucSimType_;
- ucMyChannelNum = ucInstanceNum_;
- ucMyTxType = 1;
- ucMyDeviceType = 1; // Transmission Type and Device Type will be set by simulator once loaded
- usMyMsgPeriod = 8192; // 4Hz, set to specific simulator value once loaded
- dCurEventTime = 0;
- bPairingBit = FALSE; // Pairing bit is disabled by default
- bDisplayHex = TRUE; // Display raw data in hex by default
- eMyChannelState = STATE_CHANNEL_CLOSED; // Channel is initially closed
- bMyCheckInternalRaise = FALSE;
- bAlreadyUnAssigned = FALSE; // For dealing with differences in how AP2 search timeouts
- this->tabPage_ChannelTab->Text = String::Concat("Channel ", System::Convert::ToString(ucMyChannelNum));
-
- // Create timer to handle event simulation
- this->timer_SimEvent = (gcnew System::Timers::Timer(500));
- this->timer_SimEvent->Elapsed += gcnew System::Timers::ElapsedEventHandler(this, &ANTChannel::timer_SimEvent_Tick);
-
- // Store the capabilities bytes
- sMyCapabilities.ucStandardOptions = sCapabilities_.ucStandardOptions;
- sMyCapabilities.ucAdvancedOptions = sCapabilities_.ucAdvancedOptions;
- sMyCapabilities.ucAdvancedOptions2 = sCapabilities_.ucAdvancedOptions2;
-
- switch(ucSimType)
- {
- case SIM_SENSOR:
- {
- // Display simulator list on combo box
- this->comboBox_SimSelect->Items->AddRange(gcnew cli::array< System::Object^ >(UNSELECTED) SUPPORTED_SENSORS);
- // Create a device ID based on channelNum to prevent duplicates
- usMyDeviceNum = (ucMyChannelNum*137)+100;
- this->textBox_DeviceID->Text = System::Convert::ToString(usMyDeviceNum);
- // Simulator is transmitter
- this->checkBox_TxEnable->Text = L"Transmitting";
- // Disable functionality for getting Channel ID of paired device
- this->button_getChannelID->Visible = false;
- // Keep timer alive
- System::GC::KeepAlive(timer_SimEvent);
- break;
- }
- case SIM_DISPLAY:
- {
- // Display simulator list on combo box
- this->comboBox_SimSelect->Items->AddRange(gcnew cli::array< System::Object^ >(UNSELECTED) SUPPORTED_DISPLAYS);
- // Wildcard Channel ID
- usMyDeviceNum = 0;
- this->textBox_DeviceID->Text = System::Convert::ToString(usMyDeviceNum);
- // Simulator is receiver
- this->checkBox_TxEnable->Text = L"Receiving";
- // Enable functionality for getting Channel ID of paired device
- this->button_getChannelID->Visible = true;
- // Ensure timer is disabled
- this->timer_SimEvent->Stop();
- // Disable display of simulated time (display simulation is not timer-driven)
- this->label_TxTime->Visible = false;
- this->label_TxTimeDisplay->Visible = false;
- break;
- }
- default:
- {
- // Ensure timer is disabled
- this->timer_SimEvent->Stop();
- break;
- }
- }
- // Init the TX Power Select Dropdown based on which HW platform was found
- switch (eHWType_)
- {
- case PLATFORM_AP1_ANT11TR:
- {
- this->comboBox_TxPowerSelect->Items->AddRange(gcnew cli::array< System::Object^ > TXPOWER_SETTINGS1);
- break;
- }
- case PLATFORM_AP2_USB2_AT3:
- {
- this->comboBox_TxPowerSelect->Items->AddRange(gcnew cli::array< System::Object^ > TXPOWER_SETTINGS2);
- break;
- }
- case PLATFORM_C7:
- {
- this->comboBox_TxPowerSelect->Items->AddRange(gcnew cli::array< System::Object^ > TXPOWER_SETTINGS3);
- break;
- }
- case PLATFORM_UNKNOWN:
- // fall through
- default:
- {
- this->comboBox_TxPowerSelect->Items->AddRange(gcnew cli::array< System::Object^ > TXPOWER_SETTINGS_UNKNOWN);
- break;
- }
- }
- // Make sure the dropdown starts showing the default power
- this->comboBox_TxPowerSelect->SelectedIndex = DEFAULT_RADIO_TX_POWER;
- bTXPowerUIEnabled = TRUE;
- }
- /**************************************************************************
- * ANTChannel::~ANTChannel
- *
- * ANT CHannel deconstructor - called after channels are destroyed.
- *
- * returns: N/A
- *
- **************************************************************************/
- ANTChannel::~ANTChannel()
- {
- if(curSimulator)
- {
- delete curSimulator;
- }
- delete timer_SimEvent;
- this->tabPage_ChannelTab->Controls->Clear();
- delete this->tabPage_ChannelTab;
- delete this->tabControl1;
- //clean up floating resources with the garbage collector
- GC::Collect(2);
- if (components)
- {
- delete components;
- }
- }
- /**************************************************************************
- * ANTChannel::ANTProtocolEvent
- *
- * MainForm ANT Protocol Event handler - Handles ANT responses to ANT commands and
- * requested messages from ANT
- *
- * Params:
- *
- * ucMessageCode_: Message ID of packet recieved from ANT.
- * pcBuffer_: Pointer to message buffer recieved from ANT.
- *
- * returns: N/A
- *
- **************************************************************************/
- void ANTChannel::ANTProtocolEvent(UCHAR ucMessageCode_, UCHAR* pcBuffer_)
- {
- if(ucMessageCode_ == MESG_CHANNEL_ID_ID)
- {
- // Requesting the Channel ID is only available on the receiver
- if(ucSimType == SIM_DISPLAY)
- {
- // Update Channel Parameters
- usMyDeviceNum = (USHORT) pcBuffer_[1] + ((USHORT) pcBuffer_[2] << 8);
- ucMyDeviceType = (UCHAR) pcBuffer_[3];
- ucMyTxType = (UCHAR) pcBuffer_[4];
- // Display Channel ID
- this->textBox_DeviceID->ReadOnly = FALSE;
- this->textBox_DeviceID->Text = System::Convert::ToString(usMyDeviceNum);
- this->textBox_DeviceID->ReadOnly = TRUE;
- this->textBox_DeviceType->ReadOnly = FALSE;
- this->textBox_DeviceType->Text = System::Convert::ToString(ucMyDeviceType);
- this->textBox_DeviceType->ReadOnly = TRUE;
- this->textBox_TransmissionType->ReadOnly = FALSE;
- this->textBox_TransmissionType->Text = System::Convert::ToString(ucMyTxType);
- this->textBox_TransmissionType->ReadOnly = TRUE;
- }
- }
- else if(ucMessageCode_ == MESG_RESPONSE_EVENT_ID)
- {
- // Check if this was a successful response.
- // Otherwise handle the error condition.
- if(pcBuffer_[2] == RESPONSE_NO_ERROR)
- {
- switch (pcBuffer_[1])
- {
- case MESG_ASSIGN_CHANNEL_ID:
- {
-
- if(eMyChannelState == STATE_CHANNEL_OPENING)
- {
- // Set RF Freq.
- ANTClass::SetChannelRFFreq(ucMyChannelNum, ANTPLUS_RF_FREQ);
- }
- else
- {
- System::Diagnostics::Debug::Assert(FALSE, "Invalid State");
- }
- break;
- }
- case MESG_UNASSIGN_CHANNEL_ID:
- {
- this->checkBox_TxEnable->Enabled = TRUE;
- break;
- }
-
- case MESG_CHANNEL_ID_ID:
- {
- if(eMyChannelState == STATE_CHANNEL_OPENING)
- {
- ANTClass::SetChannelPeriod(ucMyChannelNum, usMyMsgPeriod);
- }
- else
- {
- System::Diagnostics::Debug::Assert(FALSE, "Invalid State");
- }
- break;
- }
- case MESG_CHANNEL_MESG_PERIOD_ID:
- {
- if(eMyChannelState == STATE_CHANNEL_OPENING)
- {
- ANTClass::OpenChannel(ucMyChannelNum);
-
-
- }
- #ifdef INC_GEOCACHE
- else if(eMyChannelState == STATE_CHANNEL_OPEN)
- {
- // Do Nothing - this is the Response from the Dynamic Mesg Period change
- // specific to Geocache Profile ...
- }
- #endif // INC_GEOCACHE
- else
- {
- System::Diagnostics::Debug::Assert(FALSE, "Invalid State");
- }
- break;
- }
-
-
- case MESG_CHANNEL_RADIO_FREQ_ID:
- {
- if(eMyChannelState == STATE_CHANNEL_OPENING)
- {
-
- ANTClass::SetChannelId(ucMyChannelNum, usMyDeviceNum, ucMyDeviceType, ucMyTxType);
- }
- else
- {
- System::Diagnostics::Debug::Assert(FALSE, "Invalid State");
- }
- break;
- }
- case MESG_OPEN_CHANNEL_ID:
- {
- if(eMyChannelState == STATE_CHANNEL_OPENING)
- {
- eMyChannelState = STATE_CHANNEL_OPEN;
- UpdateRawTxDisplay("\nChannel Opened...", NULL);
-
- this->checkBox_TxEnable->Enabled = TRUE;
-
- if(ucSimType == SIM_SENSOR)
- {
- // Enable timer for sensor simulation
- this->timer_SimEvent->Enabled = TRUE;
- #ifdef INC_WEIGHT_SCALE
- if(comboBox_SimSelect->SelectedIndex == WEIGHT_SCALE)
- curSimulator->ANT_eventNotification(MESG_OPEN_CHANNEL_ID, NULL);
- #endif // INC_WEIGHT_SCALE
- }
- if(ucSimType == SIM_DISPLAY)
- {
- // Enable capability of obtaining channel ID of paired device on display devices
- this->button_getChannelID->Enabled = TRUE;
- #ifdef INC_GEOCACHE
- if(this->comboBox_SimSelect->SelectedIndex == GEOCACHE)
- {
- ANTClass::SetChannelSearchTimeout(ucMyChannelNum, 45); // !!! 45sec Search Timeout for Geocache Display !!!
- }
- #endif // INC_GEOCACHE
- }
- #ifdef INC_TEMPERATURE
- if(comboBox_SimSelect->SelectedIndex == TEMPERATURE)
- curSimulator->ANT_eventNotification(MESG_OPEN_CHANNEL_ID, NULL);
- #endif // INC_TEMPERATURE
-
- //Don't allow changes to channel configuration while channel is open
- this->checkBox_PairingOn->Enabled = FALSE;
- textBox_DeviceID->ReadOnly = TRUE;
- textBox_TransmissionType->ReadOnly = TRUE;
-
- #ifdef INC_CUSTOM
- if(this->comboBox_SimSelect->SelectedIndex == CUSTOM)
- {
- textBox_DeviceType->ReadOnly = TRUE;
- textBox_TransmissionType->ReadOnly = TRUE;
- textBox_TransmitPeriod->ReadOnly = TRUE;
- }
- #endif // INC_CUSTOM
- }
- else
- {
- System::Diagnostics::Debug::Assert(FALSE, "Invalid State");
- }
- break;
- }
- case MESG_CLOSE_CHANNEL_ID:
- {
- eMyChannelState = STATE_CHANNEL_CLOSED;
- timer_SimEvent->Enabled = FALSE;
- // Re-enable changes to the configuration
- textBox_DeviceID->ReadOnly = FALSE;
- textBox_TransmissionType->ReadOnly = FALSE;
- this->checkBox_PairingOn->Enabled = TRUE; // Start by default without setting the pairing bit
- this->checkBox_PairingOn->Checked = FALSE;
- bPairingBit = FALSE;
- #ifdef INC_CUSTOM
- if(this->comboBox_SimSelect->SelectedIndex == CUSTOM)
- {
- this->textBox_TransmissionType->ReadOnly = FALSE;
- this->textBox_TransmitPeriod->ReadOnly = FALSE;
- }
- #endif // INC_CUSTOM
- #ifdef INC_WEIGHT_SCALE
- if(this->comboBox_SimSelect->SelectedIndex == WEIGHT_SCALE)
- curSimulator->ANT_eventNotification(MESG_CLOSE_CHANNEL_ID, NULL);
- #endif // INC_WEIGHT_SCALE
- #ifdef INC_GEOCACHE
- if(this->comboBox_SimSelect->SelectedIndex == GEOCACHE)
- curSimulator->ANT_eventNotification(MESG_CLOSE_CHANNEL_ID, NULL);
- #endif // INC_GEOCACHE
- #ifdef INC_TEMPERATURE
- if(this->comboBox_SimSelect->SelectedIndex == TEMPERATURE)
- curSimulator->ANT_eventNotification(MESG_CLOSE_CHANNEL_ID, NULL);
- #endif // INC_TEMPERATURE
- break;
- }
- }
- }
- else
- {
- if(eMyChannelState == STATE_CHANNEL_OPENING)
- {
- ChannelOpenFailed();
- }
- if( pcBuffer_[2] == EVENT_COMMAND_TIMEOUT)
- {
- UpdateRawTxDisplay("\nCOMMAND TIMEOUT!!!!!", NULL);
- }
- }
- }
- }
- /**************************************************************************
- * ANTChannel::ANTChannelEvent
- *
- * Process ANT event
- * The display is updated accordingly, and the event is forwarded to
- * the simulator for device specific handling
- * !! IMPORTANT: only events defined here are processed by simulators
- *
- * ucEvent_: event code
- * pcBuffer_: pointer to buffer containing data received from ANT
- *
- * returns: N/A
- *
- **************************************************************************/
- void ANTChannel::ANTChannelEvent(UCHAR ucEvent_, UCHAR* pcBuffer_)
- {
- UCHAR ucBufferIndex = 1;
- switch(ucEvent_)
- {
- case EVENT_TX:
- {
- // Simulated sensors update the transmit buffer every message period
- if(ucSimType == SIM_SENSOR)
- {
- sendSimMsg();
- }
- break;
- }
- case EVENT_RX_BROADCAST:
- {
- UpdateRawTxDisplay("\nRX:", (UCHAR*) &pcBuffer_[ucBufferIndex]);
-
- // Forward to simulator for further processing
- curSimulator->ANT_eventNotification(ucEvent_, (UCHAR*) &pcBuffer_[ucBufferIndex]);
- break;
- }
- case EVENT_RX_SEARCH_TIMEOUT:
- {
- // This event should only take place on a receiver
- if(ucSimType == SIM_DISPLAY)
- {
- eMyChannelState = STATE_CHANNEL_CLOSED;
- this->checkBox_TxEnable->Checked = FALSE;
- this->checkBox_PairingOn->Enabled = TRUE;
- this->textBox_DeviceID->Enabled = TRUE;
- UpdateRawTxDisplay("\nReceiver Search Timeout", NULL);
- ANTClass::UnAssignChannel(ucMyChannelNum); // Necessary for ARCT functionality
- // the AP2 chip sends 2 commands on timeout: EVENT_RX_SEARCH_TIMEOUT AND EVENT_CHANNEL_CLOSED
- // beacuse the preceding line just unassigned the channel, for AP2, the EVENT_CHANNEL_CLOSED
- // will happen next and try to close / unassign an already unassigned channel. This flag prevents this.
- bAlreadyUnAssigned = TRUE;
- }
- break;
- }
- case EVENT_RX_ACKNOWLEDGED:
- {
- UpdateRawTxDisplay("\nRX Acknowledged Msg:\n ", (UCHAR*) &pcBuffer_[1]);
- // Forward to simulator for further processing
- curSimulator->ANT_eventNotification(ucEvent_, (UCHAR*) &pcBuffer_[1]);
- break;
- }
- case EVENT_RX_FAIL:
- {
- UpdateRawTxDisplay("\nRX Failure!", NULL);
- // Forward to simulator for further processing
- curSimulator->ANT_eventNotification(ucEvent_, pcBuffer_);
- break;
- }
- case EVENT_TRANSFER_TX_COMPLETED:
- {
- UpdateRawTxDisplay("\nTX Success!", NULL);
- // Forward to simulator for further processing
- curSimulator->ANT_eventNotification(ucEvent_, pcBuffer_);
- break;
- }
- case EVENT_TRANSFER_TX_FAILED:
- {
- UpdateRawTxDisplay("\nTX Failure!", NULL);
- // Forward to simulator for further processing
- curSimulator->ANT_eventNotification(ucEvent_, pcBuffer_);
- break;
- }
- case EVENT_CHANNEL_CLOSED:
- {
- if (bAlreadyUnAssigned == FALSE) // only unassign the channel if it is not already done
- ANTClass::UnAssignChannel(ucMyChannelNum);
- UpdateRawTxDisplay("\n...Channel Closed", NULL);
- bAlreadyUnAssigned = FALSE; // reset the flag
- break;
- }
- case EVENT_RX_FAIL_GO_TO_SEARCH:
- {
- // This event should only take place on a receiver
- if(ucSimType == SIM_DISPLAY)
- {
- UpdateRawTxDisplay("\nRepeated RX Failure,\nSearching for Signal...", NULL);
- }
- break;
- }
-
- case EVENT_ACK_TIMEOUT:
- {
- UpdateRawTxDisplay("Ack timeout...", NULL);
- // Forward to simulator for further processing
- // Only forward to receivers, as a master would get an EVENT_TRANSFER_TX_FAILED instead
- if(ucSimType == SIM_DISPLAY)
- {
- curSimulator->ANT_eventNotification(ucEvent_, NULL);
- }
- break;
-
- }
- default:
- {
- // Look up event in table
- int iIndex = Array::IndexOf(ANTEventTable::aucCode, ucEvent_);
- if(iIndex >=0 && iIndex < ANTEventTable::aucCode->Length)
- UpdateRawTxDisplay(String::Concat("\nEvent: ", ANTEventTable::aucDescr[iIndex]), NULL);
- else
- UpdateRawTxDisplay(String::Concat("\nUnknown Event:", System::Convert::ToString(ucEvent_)), NULL);
- break;
- }
- }
-
-
-
-
- }
- /**************************************************************************
- * ANTChannel::sendSimMsg
- *
- * Handle update of transmit buffer every message period, and
- * transmission of broadcast message
- * Only performed in sensor simulators
- * The pointer to the transmit buffer is provided to the simulator
- * specific ANT event handler so that it can be updated
- *
- * returns: N/A
- *
- **************************************************************************/
- void ANTChannel::sendSimMsg()
- {
- UCHAR aucTxBuffer[8] = {0,0,0,0,0,0,0,0};
- if(eMyChannelState == STATE_CHANNEL_OPEN && ucSimType == SIM_SENSOR)
- {
- // Call simulator to update transmit buffer
- curSimulator->ANT_eventNotification(EVENT_TX, aucTxBuffer);
-
- {
- // Update display
- UpdateRawTxDisplay("\nTX:", (UCHAR*) aucTxBuffer);
- // Send broadcast data
- ANTClass::SendBroadcastData(ucMyChannelNum, (UCHAR*) aucTxBuffer);
-
- }
-
-
-
- }
- }
- /**************************************************************************
- * ANTChannel::updateMesgPeriod
- *
- * Allows simulators to update message period on demand
- *
- * usMesgRate_: new message period
- *
- * returns: N/A
- *
- **************************************************************************/
- void ANTChannel::updateMesgPeriod(USHORT usMesgPeriod_)
- {
- // Update display
- UpdateRawTxDisplay(String::Concat("\nMessage Period Changed: ", usMesgPeriod_.ToString()), NULL);
- // Update Message Period
- usMyMsgPeriod = usMesgPeriod_;
- ANTClass::SetChannelPeriod(ucMyChannelNum, usMyMsgPeriod);
- }
- /**************************************************************************
- * ANTChannel::sendAckMsg
- *
- * Allows simulators to send acknowledged messages on demand
- *
- * pucTxBuffer_: pointer to buffer containing data to send
- *
- * returns: N/A
- *
- **************************************************************************/
- void ANTChannel::sendAckMsg(UCHAR* pucTxBuffer_)
- {
- USHORT usAckTimeout = (USHORT) (((ULONG) usMyMsgPeriod * 1000)/32768); // Timeout = 1 message period
- if(pucTxBuffer_)
- {
- // Update display
- UpdateRawTxDisplay("\nTX Acknowledged Msg:\n ", (UCHAR*) pucTxBuffer_);
- // Send acknowledged data
- if(ucSimType == SIM_DISPLAY)
- ANTClass::SendAcknowledgedData(ucMyChannelNum, (UCHAR*) pucTxBuffer_, usAckTimeout); // Timeout only required for receiver
- else if(ucSimType == SIM_SENSOR)
- ANTClass::SendAcknowledgedData(ucMyChannelNum, (UCHAR*) pucTxBuffer_);
- }
- }
- /**************************************************************************
- * ANTChannel::sendBroadcastMsg
- *
- * Allows simulators to send broadcast messages on demand
- * Used in display simulators when sending responses to received messages
- *
- * pucTxBuffer_: pointer to buffer containing data to send
- *
- * returns: N/A
- *
- **************************************************************************/
- void ANTChannel::sendBroadcastMsg(UCHAR* pucTxBuffer_)
- {
- if(pucTxBuffer_)
- {
- // Update display
- UpdateRawTxDisplay("\nTX:", (UCHAR*) pucTxBuffer_);
- // Send broadcast data
- ANTClass::SendBroadcastData(ucMyChannelNum, (UCHAR*) pucTxBuffer_);
- }
- }
- /**************************************************************************
- * ANTChannel::timer_SimEvent_Tick
- *
- * Called every timer event, for event driven simulators (sensors)
- * The timer interval is updated after updating device specific simulated
- * data
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void ANTChannel::timer_SimEvent_Tick(System::Object^ sender, System::Timers::ElapsedEventArgs^ e)
- {
- if(eMyChannelState == STATE_CHANNEL_OPEN && ucSimType == SIM_SENSOR)
- {
- // Update current event time (for display purposes)
- dCurEventTime += timer_SimEvent->Interval;
- this->label_TxTimeDisplay->Text = System::TimeSpan::FromSeconds(System::Math::Round(dCurEventTime/1000)).ToString();
- // Simulator specific event-driven behavior
- curSimulator->onTimerTock((USHORT) dCurEventTime);
- // Update timer interval (as per simulator)
- this->timer_SimEvent->Interval = curSimulator->getTimerInterval();
- }
- }
- /**************************************************************************
- * ANTChannel::UpdateRawTxDisplay
- *
- * Displays current event in raw box
- *
- * strLabel_: label identifying the event
- * pucBuffer_: pointer to buffer with data to display
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void ANTChannel::UpdateRawTxDisplay(System::String^ strLabel_, UCHAR* pucBuffer_)
- {
- UCHAR i;
- richTextBox_RawTxDisplay->AppendText(strLabel_);
-
- if(pucBuffer_)
- {
- for(i=0; i<8; ++i)
- {
- if(bDisplayHex)
- {
- System::String^ strTemp = System::Convert::ToString(pucBuffer_[i], 16);
- if(strTemp->Length == 1)
- richTextBox_RawTxDisplay->AppendText(System::String::Concat("[","0",strTemp, "]"));
- else
- richTextBox_RawTxDisplay->AppendText(System::String::Concat("[",strTemp, "]"));
- }
- else
- {
- richTextBox_RawTxDisplay->AppendText(System::String::Concat("[", pucBuffer_[i], "]"));
- }
- }
- }
- }
- /**************************************************************************
- * ANTChannel::button_Clear_Click
- *
- * Clears raw text box
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void ANTChannel::button_Clear_Click(System::Object^ sender, System::EventArgs^ e)
- {
- richTextBox_RawTxDisplay->Text ="";
- }
- /**************************************************************************
- * ANTChannel::checkBox_TxEnable_CheckedChanged
- *
- * Opens and closes the channel, as selected by the user
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void ANTChannel::checkBox_TxEnable_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- // Return if value of checkbox was changed internally and not by the user
- if(bMyCheckInternalRaise)
- {
- bMyCheckInternalRaise = FALSE;
- return;
- }
-
- // Disable changes while performing checks
- this->checkBox_TxEnable->Enabled = FALSE;
-
- if(!curSimulator)
- {
- // Disable opening the channel if no simulator was loaded
- bMyCheckInternalRaise=TRUE;
- this->checkBox_TxEnable->Checked = FALSE;
- this->checkBox_TxEnable->Enabled = TRUE;
-
- UpdateRawTxDisplay("\nChoose Simulator First ...", NULL);
-
- }
- else if(checkBox_TxEnable->Checked && curSimulator)
- {
- // Check channel parameters are valid (in case they were modified by the user)
- if(!ValidateChannelID())
- {
- // Return if channel parameters are incorrect
- UpdateRawTxDisplay("\nChannel Setup Failed: Bad Channel Parameters", NULL);
- bMyCheckInternalRaise = TRUE;
- this->checkBox_TxEnable->Checked = FALSE;
- this->checkBox_TxEnable->Enabled = TRUE;
- eMyChannelState = STATE_CHANNEL_CLOSED;
- return;
- }
-
- switch(ucSimType)
- {
- // Open Channel
- case SIM_SENSOR:
- OpenChannel(PARAMETER_TX_NOT_RX);
- break;
- case SIM_DISPLAY:
- OpenChannel(PARAMETER_RX_NOT_TX);
- break;
- default:
- eMyChannelState = STATE_CHANNEL_CLOSED;
- break;
- }
- // Reassert the TX Power level in case the user selected
- comboBox_TxPowerSelect_SelectedIndexChanged(sender, e);
- }
- else
- {
- if(eMyChannelState == STATE_CHANNEL_OPEN)
- {
- // Only close if channel was previously open
- ANTClass::CloseChannel(ucMyChannelNum);
- }
- }
- }
- /**************************************************************************
- * ANTChannel::comboBox_SimSelect_SelectedIndexChanged
- *
- * Handles selection of simulator to load.
- * Selecting the same simulator will cause it to reload, resetting to
- * initial values
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void ANTChannel::comboBox_SimSelect_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) {
- //Delete last simulator
- if(curSimulator)
- delete curSimulator;
- // By default, unset pairing bit
- this->checkBox_PairingOn->Checked = FALSE;
- bPairingBit = FALSE;
-
- // Reset simulation timer
- dCurEventTime = 0;
- if(SIM_SENSOR)
- {
- this->label_TxTimeDisplay->Text = "0";
- }
- // Load simulator
- switch(comboBox_SimSelect->SelectedIndex)
- {
- #ifdef INC_HRM
- case HEART_RATE_MONITOR:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew HRMSensor(timer_SimEvent);
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew HRMDisplay();
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif // INC_HRM
- #ifdef INC_SDM
- case SPEED_DISTANCE_MONITOR:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew SDMSensor(timer_SimEvent,gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew SDMDisplay(gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg)); // modified to add Tx
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif // INC_HRM
- #ifdef INC_BIKE_POWER
- case BIKE_POWER:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew BikePowerSensor(timer_SimEvent, gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew BikePowerDisplay(gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif // INC_BIKE_POWER
- #ifdef INC_BIKE_SPEED_CADENCE
- case BIKE_SPDCAD:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew BikeSpdCadSensor(timer_SimEvent);
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew BikeSpdCadDisplay();
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif // INC_BIKE_SPEED_CADENCE
- #ifdef INC_BIKE_CADENCE
- case BIKE_CADENCE:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew BikeCadenceSensor(timer_SimEvent);
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew BikeCadenceDisplay();
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif // BIKE_CADENCE
- #ifdef INC_BIKE_SPEED
- case BIKE_SPEED:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew BikeSpeedSensor(timer_SimEvent);
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew BikeSpeedDisplay();
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif // INC_BIKE_SPEED
- #ifdef INC_WEIGHT_SCALE
- case WEIGHT_SCALE:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew WeightScaleSensor(timer_SimEvent);
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew WeightScaleDisplay(gcnew dRequestBcastMsg(this,&ANTChannel::sendBroadcastMsg));
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif //INC_WEIGHT_SCALE
- #ifdef INC_MSM
- case MULTISPORT_SPEED_DISTANCE:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew MSMSensor(timer_SimEvent, gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew MSMDisplay(gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif //INC_MSM
- #ifdef INC_LEV
- case LIGHT_ELECTRIC_VEHICLE:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew LEVSensor(timer_SimEvent, gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew LEVDisplay(gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg), gcnew dRequestBcastMsg(this,&ANTChannel::sendBroadcastMsg));
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif //INC_LEV
- #ifdef INC_GEOCACHE
- case GEOCACHE:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew GeocacheSensor(timer_SimEvent, gcnew dRequestAckMsg(this, &ANTChannel::sendAckMsg), gcnew dRequestUpdateMesgPeriod(this, &ANTChannel::updateMesgPeriod));
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew GeocacheDisplay(timer_SimEvent, gcnew dRequestAckMsg(this, &ANTChannel::sendAckMsg), gcnew dRequestBcastMsg(this, &ANTChannel::sendBroadcastMsg));
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif //INC_GEOCACHE
- #ifdef INC_RACQUET
- case RACQUET:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew RacquetSensor(timer_SimEvent, gcnew dRequestAckMsg(this, &ANTChannel::sendAckMsg));
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew RacquetDisplay(timer_SimEvent, gcnew dRequestAckMsg(this, &ANTChannel::sendAckMsg), gcnew dRequestBcastMsg(this, &ANTChannel::sendBroadcastMsg));
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif // INC_RACQUET
- #ifdef INC_TEMPERATURE
- case TEMPERATURE:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew TemperatureSensor(timer_SimEvent, gcnew dRequestUpdateMesgPeriod(this, &ANTChannel::updateMesgPeriod));
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew TemperatureDisplay(timer_SimEvent, gcnew dRequestAckMsg(this, &ANTChannel::sendAckMsg), gcnew dRequestUpdateMesgPeriod(this, &ANTChannel::updateMesgPeriod));
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif // INC_TEMPERATURE
- #ifdef INC_CUSTOM
- case CUSTOM:
- switch(ucSimType)
- {
- #ifdef SIM_TX
- case SIM_SENSOR:
- curSimulator = gcnew CustomSensor(timer_SimEvent, gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
- break;
- #endif // SIM_TX
- #ifdef SIM_RX
- case SIM_DISPLAY:
- curSimulator = gcnew CustomDisplay(gcnew dRequestAckMsg(this,&ANTChannel::sendAckMsg));
- break;
- #endif // SIM_RX
- default:
- break;
- }
- break;
- #endif // INC_CUSTOM
- default:
- return;
- }
- // Obtain channel parameters from simulator
- ucMyDeviceType = curSimulator->getDeviceType();
- ucMyTxType = curSimulator->getTransmissionType();
- usMyMsgPeriod = curSimulator->getTransmitPeriod();
-
- // Update display of channel parameters
- this->textBox_DeviceType->Text = ucMyDeviceType.ToString();
- this->textBox_DeviceType->ReadOnly = TRUE;
- this->textBox_TransmissionType->Text = ucMyTxType.ToString();
- this->textBox_TransmitPeriod->Text = usMyMsgPeriod.ToString();
- this->textBox_TransmitPeriod->ReadOnly = TRUE;
- this->tabPage_ChannelTab->Controls->Add(curSimulator->getSimSettingsPanel());
- this->tabPage_ChannelTab->Controls->Add(curSimulator->getSimTranslatedDisplay());
-
- // Ensure channel is closed
- this->checkBox_TxEnable->Checked = FALSE;
- eMyChannelState = STATE_CHANNEL_CLOSED;
- if(ucSimType == SIM_SENSOR)
- {
- this->timer_SimEvent->Interval = curSimulator->getTimerInterval();
- }
- }
- /**************************************************************************
- * ANTChannel::checkBox_PairingOn_CheckedChange
- *
- * Enables/disables pairing bit, per user input (GUI)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void ANTChannel::checkBox_PairingOn_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- if(this->checkBox_PairingOn->Checked)
- {
- bPairingBit = TRUE;
- }
- else
- {
- bPairingBit = FALSE;
- }
- SetPairingBit();
- }
- /**************************************************************************
- * ANTChannel::checkBox_DisplayAsHex_CheckedChanged
- *
- * Selects whether data is displayed as hex or decimal, per user input (GUI)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void ANTChannel::checkBox_DisplayAsHex_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- if(this->checkBox_DisplayAsHex->Checked)
- {
- bDisplayHex = TRUE;
- }
- else
- {
- bDisplayHex = FALSE;
- }
- }
- /**************************************************************************
- * ANTChannel::button_getChannelID_Click
- *
- * Requests channel ID
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void ANTChannel::button_getChannelID_Click(System::Object^ sender, System::EventArgs^ e) {
- // Request Device Number of device we are pairing to, response is handled in main function that handles incoming events
- if(ucSimType == SIM_DISPLAY)
- {
- ANTClass::RequestMessage(ucMyChannelNum, MESG_CHANNEL_ID_ID);
- }
- }
- /**************************************************************************
- * ValidateChannelID
- *
- * Validates input boxes for Channel ID and Message Period
- *
- * returns: TRUE if the parameters are valid
- *
- **************************************************************************/
- BOOL ANTChannel::ValidateChannelID()
- {
- BOOL bSuccess = TRUE;
- try
- {
- ucMyDeviceType = System::Convert::ToByte(this->textBox_DeviceType->Text);
- ucMyTxType = System::Convert::ToByte(this->textBox_TransmissionType->Text);
- usMyDeviceNum = System::Convert::ToUInt16(this->textBox_DeviceID->Text);
- usMyMsgPeriod = System::Convert::ToUInt16(this->textBox_TransmitPeriod->Text);
- SetPairingBit();
- }
- catch(...)
- {
- bSuccess = FALSE;
- //MessageBox::Show("Invalid Input", "Invalid Channel Parameters", MessageBoxButtons::OK,MessageBoxIcon::Error, MessageBoxDefaultButton::Button1);
- }
- return bSuccess;
- }
- /**************************************************************************
- * SetPairingBit
- *
- * Sets/unsets pairing bit in Channel ID
- *
- * returns: N/A
- *
- **************************************************************************/
- void ANTChannel::SetPairingBit()
- {
- if(bPairingBit)
- ucMyDeviceType |= 0x80; // set pairing bit
- else
- ucMyDeviceType &= ~0x80; // clear pairing bit
- // Update text box
- //this->textBox_DeviceType->Text = System::Convert::ToString(ucMyDeviceType);
- }
- /**************************************************************************
- * OpenChannel
- *
- * Initiates the opening of a channel by setting the proper state and sending
- * an assign channel command.
- *
- * Params:
- *
- * ucChannelType_: ANT Channel type as either MASTER (0x10) or SLAVE (0x00)
- *
- * returns: TRUE if the parameters are valid
- *
- **************************************************************************/
- BOOL ANTChannel::OpenChannel(UCHAR ucChannelType_)
- {
- //!! Verify input parameters
- eMyChannelState = STATE_CHANNEL_OPENING;
- ANTClass::AssignChannel(ucMyChannelNum, ucChannelType_, ANTPLUS_NETWORK_NUMBER);
-
- return TRUE;
- }
- /**************************************************************************
- * ChannelOpenFailed
- *
- * Called when opening of the ANT channel fails. Resets the proper state
- * variables and displays error message.
- *
- * returns: N/A
- *
- **************************************************************************/
- void ANTChannel::ChannelOpenFailed()
- {
- UpdateRawTxDisplay("\nChannel Setup Failed", NULL);
- bMyCheckInternalRaise = TRUE;
- checkBox_TxEnable->Checked = FALSE;
- checkBox_TxEnable->Enabled = TRUE;
- eMyChannelState = STATE_CHANNEL_CLOSED;
- }
- /**************************************************************************
- * comboBox_TxPowerSelect_SelectedIndexChanged
- *
- * User may change TxPower level if desired before opening channel. If
- * device reports PER_CHANNEL_TX_POWER the SetChannelTXPower() command
- * is used affecting . Otherwise SetTransmitPower command is used and
- * all channel tabs must be updated.
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void ANTChannel::comboBox_TxPowerSelect_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
- {
- UCHAR ucNewPower;
- ucNewPower = this->comboBox_TxPowerSelect->SelectedIndex;
- // Only generate commands in response to user events, not init or other programmatic changes to index
- if (bTXPowerUIEnabled == TRUE)
- {
- // Assert the new power
- // Use Per Channel TX Power command if possible
- if (sMyCapabilities.ucAdvancedOptions & CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED)
- {
- ANTClass::SetChannelTxPower(ucMyChannelNum, ucNewPower);
- }
- else
- {
- ANTClass::SetTransmitPower(ucNewPower);
- ANTChannel::iTheTXPowerLevel = ucNewPower;
- }
- }
- }
- /**************************************************************************
- * tabPage_ChannelTab_Enter
- *
- * Update the TX Power dropdown if needed. This could be caused if both the
- * Channel TX Power Command is not supported and the user may have adjusted
- * the TX Power on another channel.
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void ANTChannel::tabPage_ChannelTab_Enter(System::Object^ sender, System::EventArgs^ e)
- {
- // Are we using the global TX Power Command (=>per channel not supported)?
- if (~sMyCapabilities.ucAdvancedOptions & CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED)
- {
- // Has another channel changed the power level?
- if (this->comboBox_TxPowerSelect->SelectedIndex != ANTChannel::iTheTXPowerLevel)
- {
- // Disable the TX Power Select Dropdown handler and update the index
- bTXPowerUIEnabled = FALSE;
- this->comboBox_TxPowerSelect->SelectedIndex = ANTChannel::iTheTXPowerLevel;
- bTXPowerUIEnabled = TRUE;
- }
- }
- }
|