Radio Structures in OOP

Dependencies:   mbed mbed-rtos

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CommModule.cpp Source File

CommModule.cpp

00001 #include "CommModule.h"
00002 
00003 // Set the class's constants for streamlined use in other areas of the code
00004 const int CommModule::TX_QUEUE_SIZE = COMM_MODULE_TX_QUEUE_SIZE;
00005 const int CommModule::RX_QUEUE_SIZE = COMM_MODULE_RX_QUEUE_SIZE;
00006 const int CommModule::NBR_PORTS = COMM_MODULE_NBR_PORTS;
00007 
00008 // Default constructor
00009 CommModule::CommModule() :
00010     // [X] - 1.1 - Define the data queues.
00011     // =================
00012     _txQueueHelper(),
00013     _rxQueueHelper()
00014 {
00015     // [X] - 1.2 - Create the data queues.
00016     // =================
00017     _txQueue = osMailCreate(_txQueueHelper.def(), NULL);
00018     _rxQueue = osMailCreate(_rxQueueHelper.def(), NULL);
00019 
00020     // [X] - 2.1 - Define the TX & RX task threads.
00021     // =================
00022     define_thread(_txDef, &CommModule::txThread);
00023     define_thread(_rxDef, &CommModule::rxThread);
00024 
00025     // [X] - 2.2 - Create the TX & RX threads - pass them a pointer to the created object.
00026     // =================
00027     _txID = osThreadCreate(&_txDef, (void*)this);
00028     _rxID = osThreadCreate(&_rxDef, (void*)this);
00029 
00030     _txH_called = false;
00031 }
00032 
00033 CommModule::~CommModule()
00034 {
00035     if (_open_ports)
00036         delete _open_ports;
00037 }
00038 
00039 void CommModule::txThread(void const *arg)
00040 {
00041     CommModule *inst = (CommModule*)arg;
00042 
00043     // Only continue past this point once at least one (1) hardware link is initialized
00044     osSignalWait(COMM_MODULE_SIGNAL_START_THREAD, osWaitForever);
00045 
00046     LOG("TX Ready!\r\n");
00047 
00048     while(1) {
00049 
00050         // When a new RTP packet is put in the tx queue, begin operations (does nothing if no new data in queue)
00051         osEvent evt = osMailGet(inst->_txQueue, osWaitForever);
00052 
00053         if (evt.status == osEventMail) {
00054 
00055             // Get a pointer to the packet's memory location
00056             RTP_t *p = (RTP_t*)evt.value.p;
00057 
00058             // Send the packet on the active communication link
00059             inst->_tx_handles[p->port].call(p);
00060 
00061             EVENT("Transmission:    Port: %u    Subclass: %u\r\n", p->port, p->subclass);
00062 
00063             // Release the allocated memory once data is sent
00064             osMailFree(inst->_txQueue, p);
00065         }
00066     }
00067 }
00068 
00069 void CommModule::rxThread(void const *arg)
00070 {
00071     CommModule *inst = (CommModule*)arg;
00072 
00073     // Only continue past this point once at least one (1) hardware link is initialized
00074     osSignalWait(COMM_MODULE_SIGNAL_START_THREAD, osWaitForever);
00075 
00076     LOG("RX Ready!\r\n");
00077 
00078     RTP_t *p;
00079     osEvent  evt;
00080     while(1) {
00081 
00082         // Wait until new data is placed in the class's rxQueue from a CommLink class
00083         evt = osMailGet(inst->_rxQueue, osWaitForever);
00084 
00085         if (evt.status == osEventMail) {
00086             DigitalOut led(LED4, 1);
00087 
00088             // get a pointer to where the data is stored
00089             p = (RTP_t*)evt.value.p;
00090 
00091             // If there is an open socket for the port, call it.
00092             if (std::binary_search(inst->_open_ports->begin(), inst->_open_ports->end(), p->port)) {
00093                 inst->_rx_handles[p->port].call();
00094             }
00095 
00096             EVENT("Reception: \r\n  Port: %u\r\n  Subclass: %u\r\n", p->port, p->subclass);
00097 
00098             osMailFree(inst->_rxQueue, p);  // free memory allocated for mail
00099 
00100         }
00101     }
00102 }
00103 
00104 void CommModule::TxHandler(void(*ptr)(RTP_t*), uint8_t portNbr)
00105 {
00106     _txH_called = true;
00107     ready();
00108     _tx_handles[portNbr].attach(ptr);
00109 }
00110 
00111 void CommModule::RxHandler(void(*ptr)(RTP_t*), uint8_t portNbr)
00112 {
00113     ready();
00114     _rx_handles[portNbr].attach(ptr);
00115 }
00116 
00117 void CommModule::RxHandler(void(*ptr)(void), uint8_t portNbr)
00118 {
00119     ready();
00120     _rx_handles[portNbr].attach(ptr);
00121 }
00122 
00123 
00124 void CommModule::openSocket(CommLink *link, void(*rx)(void const *arg), uint8_t portNbr)
00125 {
00126     ready();
00127     if (_txH_called) {
00128         if (std::binary_search(_open_ports->begin(), _open_ports->end(), portNbr)) {
00129             WARNING("Port number %u already binded to open socket.\r\n", portNbr);
00130         } else {
00131             // [X] - 1 - Add the port number to the list of active ports & keep sorted
00132             _open_ports->push_back(portNbr);
00133             std::sort(_open_ports->begin(), _open_ports->end());
00134 
00135             // [X] - 2 - Set the passed communication link object's pointer to the link pointers array.
00136             // =================
00137             _link[portNbr] = link;
00138 
00139             // [X] - 3 - Associate the given port number with the passed function pointer.
00140             // =================
00141             _rx_handles[portNbr].attach(rx);
00142 
00143             LOG("Port %u ready for RX.\r\n", portNbr);
00144         }
00145     }
00146 }
00147 
00148 void CommModule::openSocket(uint8_t portNbr)
00149 {
00150     ready();
00151     if (_txH_called) {
00152         if (std::binary_search(_open_ports->begin(), _open_ports->end(), portNbr)) {
00153             WARNING("Port number %u already opened.\r\n", portNbr);
00154         } else {
00155             // [X] - 1 - Add the port number to the list of active ports & keep sorted
00156             _open_ports->push_back(portNbr);
00157             std::sort(_open_ports->begin(), _open_ports->end());
00158 
00159             LOG("Port %u opened.\r\n", portNbr);
00160         }
00161     } else {
00162         WARNING("Must set TX & RX callback functions before opening socket.\r\n");
00163     }
00164 }
00165 
00166 template <class T>
00167 void openSocket(T *tptr, void(T::*mptr)(void const *arg), uint8_t portNbr)
00168 {
00169 
00170 }
00171 
00172 
00173 void CommModule::ready(void)
00174 {
00175     static bool isReady = false;
00176 
00177     if (isReady) {
00178         return;
00179     }
00180 
00181     isReady = true;
00182 
00183     _open_ports = new std::vector<uint8_t>;
00184 
00185     osSignalSet(_txID, COMM_MODULE_SIGNAL_START_THREAD);
00186     osSignalSet(_rxID, COMM_MODULE_SIGNAL_START_THREAD);
00187 }
00188 
00189 
00190 void CommModule::send(RTP_t& packet)
00191 {
00192     // [X] - 1 - Check to make sure a socket for the port exists
00193     if (std::binary_search(_open_ports->begin(), _open_ports->end(), packet.port)) {
00194 
00195         // [X] - 1.1 - Allocate a block of memory for the data.
00196         // =================
00197         RTP_t *p = (RTP_t*)osMailAlloc(_txQueue, osWaitForever);
00198 
00199         // [X] - 1.2 - Copy the contents into the allocated memory block
00200         // =================
00201         p->port = packet.port;
00202         p->subclass = packet.subclass;
00203         p->data_size = packet.data_size;
00204 
00205         for (int i=0; i<(sizeof(packet)/sizeof(uint8_t)); i++)
00206             p->data[i] = packet.data[i];
00207 
00208         // [X] - 1.3 - Place the passed packet into the txQueue.
00209         // =================
00210         osMailPut(_txQueue, p);
00211     } else {
00212         WARNING("Failure to send packet: There is no open socket for port %u.\r\n", packet.port);
00213     }
00214 }
00215 
00216 
00217 void CommModule::receive(RTP_t& packet)
00218 {
00219     // [X] - 1 - Check to make sure a socket for the port exists
00220     if (std::binary_search(_open_ports->begin(), _open_ports->end(), packet.port)) {
00221 
00222         // [X] - 1.1 - Allocate a block of memory for the data.
00223         // =================
00224         RTP_t *p = (RTP_t*)osMailAlloc(_rxQueue, osWaitForever);
00225 
00226         // [X] - 1.2 - Copy the contents into the allocated memory block
00227         // =================
00228         p->port = packet.port;
00229         p->subclass = packet.subclass;
00230 
00231         for (int i=0; i<packet.data_size; i++)
00232             p->data[i] = packet.data[i];
00233 
00234         // [X] - 1.3 - Place the passed packet into the txQueue.
00235         // =================
00236         osMailPut(_rxQueue, p);
00237     } else {
00238         WARNING("Received pack from unopen port %u.\r\n", packet.port);
00239     }
00240 }