void CDMRSlot::insertSilence(unsigned char newSeqNo) { // Check to see if we have any spaces to fill unsigned char seqNo = m_seqNo + 1U; if (newSeqNo == seqNo) return; unsigned char data[DMR_FRAME_LENGTH_BYTES + 2U]; ::memcpy(data, m_lastFrame, DMR_FRAME_LENGTH_BYTES + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; unsigned char n = (m_n + 1U) % 6U; unsigned int count = 0U; while (seqNo < newSeqNo) { if (n == 0U) { // Add the voice sync CDMRSync sync; sync.addSync(data + 2U, DST_BS_AUDIO); } else { // Set the embedded signalling to be nulls ::memset(data + 16U, 0x00U, 5U); // Change the color code in the EMB // XXX Note that the PI flag is lost here CEMB emb; emb.setPI(false); emb.setLCSS(0U); emb.setColorCode(m_colorCode); emb.getData(data + 2U); } data[0U] = TAG_DATA; data[1U] = 0x00U; writeQueue(data); m_seqNo = seqNo; m_n = n; count++; m_frames++; m_lost++; seqNo++; n = (n + 1U) % 6U; } LogMessage("DMR Slot %u, inserted %u audio frames", m_slotNo, count); }
void *roundRobinScheduler(void *pc) { pktcore_t *pcore = (pktcore_t *)pc; List *keylst; int nextqid, qcount, rstatus, pktsize; char *nextqkey; gpacket_t *in_pkt; simplequeue_t *nextq; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); while (1) { verbose(2, "[roundRobinScheduler]:: Round robin scheduler processing... "); keylst = map_keys(pcore->queues); nextqid = pcore->lastqid; qcount = list_length(keylst); pthread_mutex_lock(&(pcore->qlock)); if (pcore->packetcnt == 0) pthread_cond_wait(&(pcore->schwaiting), &(pcore->qlock)); pthread_mutex_unlock(&(pcore->qlock)); pthread_testcancel(); do { nextqid = (1 + nextqid) % qcount; nextqkey = list_item(keylst, nextqid); // get the queue.. nextq = map_get(pcore->queues, nextqkey); // read the queue.. rstatus = readQueue(nextq, (void **)&in_pkt, &pktsize); if (rstatus == EXIT_SUCCESS) { pcore->lastqid = nextqid; writeQueue(pcore->workQ, in_pkt, pktsize); } } while (nextqid != pcore->lastqid && rstatus == EXIT_FAILURE); list_release(keylst); pthread_mutex_lock(&(pcore->qlock)); if (rstatus == EXIT_SUCCESS) pcore->packetcnt--; pthread_mutex_unlock(&(pcore->qlock)); usleep(rconfig.schedcycle); } }
int copy2Queue(simplequeue_t *msgqueue, void *data, int size) { uchar *lpkt; if ((lpkt = (uchar *)malloc(size)) == NULL) { fatal("[copy2Queue]:: unable to allocate memory for copy packet..."); return EXIT_FAILURE; } memcpy(lpkt, data, size); if (writeQueue(msgqueue, lpkt, size) == EXIT_FAILURE) free(lpkt); return EXIT_SUCCESS; }
int ARPSend2Output(gpacket_t *pkt) { int vlevel; if (pkt == NULL) { verbose(1, "[ARPSend2Output]:: NULL pointer error... nothing sent"); return EXIT_FAILURE; } vlevel = prog_verbosity_level(); if (vlevel >= 3) printGPacket(pkt, vlevel, "ARP_ROUTINE"); return writeQueue(pcore->outputQ, (void *)pkt, sizeof(gpacket_t)); }
int classicalDecisionQProcessor(pktcore_t *pcore, gpacket_t *pkt) { ftentry_t *entry_res = checkFlowTable(pcore->flowtable, pkt); int (*processor)(gpacket_t *); if (entry_res == NULL) { printf("[decisionProcessor]:: Cannot find action to given packet...Drop!\n"); return EXIT_FAILURE; } else if (entry_res->language == C_FUNCTION) { verbose(2, "[decisionProcessor]:: Entry found protocol: %#06x C Function: Action: (0x%lx)\n", entry_res->ip_protocol_type, (unsigned long) entry_res->action); processor = entry_res->action; int nextlabel = (*processor)(pkt); if (nextlabel == NULL_PROTOCOL) return EXIT_SUCCESS; verbose(2, "[decisionProcessor][Ft]New style round"); labelNext(pkt, entry_res->ip_protocol_type, nextlabel); writeQueue(pcore->decisionQ, pkt, sizeof (gpacket_t)); verbose(2, "[decisionProcessor]:: Wrote back to decision Q..."); } else if (entry_res->language == PYTHON_FUNCTION) { verbose(2, "[decisionProcessor]:: Entry found protocol: %#06x Python Function: Action: (0x%lx)\n", entry_res->ip_protocol_type, (unsigned long) entry_res->action); PyObject * PyActionFun, *PyPkt, *PyFunReturn; PyActionFun = entry_res->action; PyPkt = SWIG_NewPointerObj((void *) pkt, SWIGTYPE_p__gpacket_t, 1); if (PyPkt) { /*TODO: handle PyReturn for further process*/ verbose(2, "[decisionProcessor]:: Ready to call Python function"); printf("[classicalDecisionQProcessor] check lock..\n"); PyEval_AcquireLock(); verbose(2, "got the lock\n"); PyFunReturn = PyObject_CallFunction(PyActionFun, "O", PyPkt); printf("[classicalDecisionQProcessor]ready to release lock\n"); PyEval_ReleaseLock(); CheckPythonError(); } } }
//------------------------------------------------------------------------------------------------- QCommandPrompt::QCommandPrompt(QWidget *parent) :QPlainTextEdit(parent) ,m_sPrompt("Lua") ,m_sPromptChar(">") ,m_vHistory() ,m_vLineQueue() ,m_pTimerQueue(new QTimer(this)) ,m_font() ,m_mtxLineQueue() ,m_colDefault(Qt::darkBlue) ,m_nHistPos(0) ,m_nMaxLines(200) ,m_nMaxHist(5) ,m_nPromptPos() ,m_nTimerInterval(50) ,m_nBlockSize(200) ,m_bIsMuted(false) { setAcceptDrops(true); // drops will be accepted (filenames and commands) setUndoRedoEnabled(false); // undo is not necessary in a console setTabChangesFocus(false); // tab will be needed for auto completion setLineWrapMode(QPlainTextEdit::NoWrap); m_pTimerQueue->setSingleShot(false); m_pTimerQueue->start(m_nTimerInterval); connect(m_pTimerQueue, SIGNAL(timeout()), this, SLOT(writeQueue())); /* QStringList vWordList; vWordList.push_back("abcd"); vWordList.push_back("efgh"); vWordList.push_back("aaaaaa"); m_pCompleter = new QCompleter(vWordList); m_pCompleter->setCaseSensitivity(Qt::CaseSensitive); //Make caseInsensitive selection m_pCompleter->setCompletionMode(QCompleter::InlineCompletion); //Used to enable in line searching this->setCompleter(m_pCompleter); */ document()->setMaximumBlockCount(m_nMaxLines); }
// WCWeightFairQueuer: function called by the classifier to enqueue // the packets.. // TODO: Debug this function... void *weightedFairScheduler(void *pc) { pktcore_t *pcore = (pktcore_t *)pc; List *keylst; int nextqid, qcount, rstatus, pktsize; char *nextqkey; gpacket_t *in_pkt; simplequeue_t *nextq; long queueSizes[100]; //Array to store bytes sent for each queue id int PacketsSent[10]; int i, j;//To iterate through the queue length array long crtStarvedQid; double crtStarvedQidWeight; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); while (1) { verbose(1, "[weightedFairScheduler]:: Weighted Fair Queue schedule processing... "); keylst = map_keys(pcore->queues); qcount = list_length(keylst); pthread_mutex_lock(&(pcore->qlock)); if (pcore->packetcnt == 0) pthread_cond_wait(&(pcore->schwaiting), &(pcore->qlock)); pthread_mutex_unlock(&(pcore->qlock)); pthread_testcancel(); for(i = 0; i <qcount; i++) { nextqkey = list_item(keylst, i); // get the queue.. nextq = map_get(pcore->queues, nextqkey); if(GetQueueSize(nextq) > 0) { crtStarvedQidWeight = (queueSizes[i] / (nextq->weight) ); //TODO crtStarvedQid = i; break; } } if(i == qcount) { list_release(keylst); usleep(rconfig.schedcycle); continue; } for(j = i; j < qcount; j++) { nextqkey = list_item(keylst, j); // get the queue.. nextq = map_get(pcore->queues, nextqkey); if(( (queueSizes[j] / (nextq->weight)) < crtStarvedQidWeight) && (GetQueueSize(nextq) > 0)) //TODO { crtStarvedQid = j; crtStarvedQidWeight = queueSizes[j] / (nextq->weight) ; //TODO } } nextqid = crtStarvedQid; nextqkey = list_item(keylst, nextqid); // get the queue.. nextq = map_get(pcore->queues, nextqkey); // read the queue.. rstatus = readQueue(nextq, (void **)&in_pkt, &pktsize);//Here we get the packet size. if (rstatus == EXIT_SUCCESS) { writeQueue(pcore->workQ, in_pkt, pktsize); verbose(1, "[weightedFairScheduler---Just sent]:: Queue[%d] has now sent %lu bytes", nextqid, queueSizes[nextqid]); queueSizes[nextqid] = queueSizes[nextqid] + findPacketSize(&(in_pkt->data));//Storing updated data sent in array PacketsSent[nextqid]++; } for(i = 0; i <qcount; i++) { nextqkey = list_item(keylst, i); // get the queue.. nextq = map_get(pcore->queues, nextqkey); verbose(1, "Packets Queued[%d] = %d, Bytes sent = %d, Packets Sent = %d", i, GetQueueSize(nextq), queueSizes[i], PacketsSent[i]); } list_release(keylst); pthread_mutex_lock(&(pcore->qlock)); if (rstatus == EXIT_SUCCESS) { (pcore->packetcnt)--; } pthread_mutex_unlock(&(pcore->qlock)); usleep(rconfig.schedcycle); } }
/*---------------------------------------------------------------------------------------- * Purpose: send out the rib table of a session * Input: ID of a session * Queue rwiter * time for each session to tranfer data * Output: 0 means success, -1 means failure * He Yan @ Jun 22, 2008 * Mikhail Strizhov @ July 23, 2010 * -------------------------------------------------------------------------------------*/ int sendRibTable(int sessionID, QueueWriter labeledQueueWriter, int transfer_time) { int i,j, error; int xml_message_counter = 0; u_int32_t num_of_sleeps = 0; int indexes_per_second=0, index_counter=0, timethrloop=0; // get time when we enter this function time_t function_start_stamp, current_time_stamp, function_end_stamp, desired_time; // for printing time char desired_time_extended[64]; memset(desired_time_extended, 0, 64); #ifdef DEBUG struct tm * desired_tm = NULL; #endif // get time function_start_stamp = time(NULL); Session_structp session; if( sessionID == -1 ) { log_err ("Failed to send a rib table of session %d", sessionID); num_of_sleeps = transfer_time / THREAD_CHECK_INTERVAL; for (i=0; i < num_of_sleeps; i++) { sleep(THREAD_CHECK_INTERVAL); // after sleep update thread time PeriodicEvents.routeRefreshThreadLastAction = time(NULL); // check if BGPmon is closing if ( PeriodicEvents.shutdown != FALSE ) { return -1; } } sleep(transfer_time % THREAD_CHECK_INTERVAL); // after sleep update thread time PeriodicEvents.routeRefreshThreadLastAction = time(NULL); return -1; } else session = Sessions[sessionID]; // send TABLE_START message with sessionID BMF bmf_start = createBMF( sessionID, BMF_TYPE_TABLE_START ); writeQueue( labeledQueueWriter, bmf_start ); if( session == NULL || session->attributeTable == NULL ) { log_err ("Failed to send a rib table of session %d", sessionID); num_of_sleeps = transfer_time / THREAD_CHECK_INTERVAL; for (i=0; i < num_of_sleeps; i++) { sleep(THREAD_CHECK_INTERVAL); // after sleep update thread time PeriodicEvents.routeRefreshThreadLastAction = time(NULL); // check if BGPmon is closing if ( PeriodicEvents.shutdown != FALSE ) { return -1; } } sleep(transfer_time % THREAD_CHECK_INTERVAL); // after sleep update thread time PeriodicEvents.routeRefreshThreadLastAction = time(NULL); return -1; } // calculate how many messages we need to send per second indexes_per_second = session->attributeTable->tableSize / transfer_time; if (indexes_per_second < 1) { indexes_per_second = 1; log_warning("Session %d, Indexes per seconds in table transfer is too low, set it to 1", sessionID); } #ifdef DEBUG debug(__FUNCTION__, "Session %d, indexes per second is %d, transfer_time is %d", sessionID, indexes_per_second, transfer_time); #endif // to through table size // remember - tablesize is an index table and has different number of attribute entries inside for (i=0; i<session->attributeTable->tableSize; i++) { // check i index is eq to send rate if ( index_counter == indexes_per_second) { #ifdef DEBUG debug(__FUNCTION__, "index is %d", i); #endif // update refresh time PeriodicEvents.routeRefreshThreadLastAction = time(NULL); // close BGPmon if shutdown is enabled if ( PeriodicEvents.shutdown != FALSE ) { return -1; } // reset index to 0 index_counter = 0; // assume that each send block (messages_per_second ) will take 1 second timethrloop++; current_time_stamp = time(NULL); desired_time = function_start_stamp + timethrloop; #ifdef DEBUG debug(__FUNCTION__, "Desired time - current time stamp is %f",difftime(desired_time, current_time_stamp)); #endif if ( (int)(difftime(desired_time, current_time_stamp)) > 2) { #ifdef DEBUG debug(__FUNCTION__, "going to sleep for %f seconds", difftime(desired_time, current_time_stamp)); #endif int difference = (int)(difftime(desired_time, current_time_stamp)); num_of_sleeps = difference / THREAD_CHECK_INTERVAL; for (j=0; j < num_of_sleeps; j++) { sleep(THREAD_CHECK_INTERVAL); // after sleep update thread time PeriodicEvents.routeRefreshThreadLastAction = time(NULL); // check if BGPmon is closing if ( PeriodicEvents.shutdown != FALSE ) { return -1; } } sleep(difference % THREAD_CHECK_INTERVAL); // after sleep update thread time PeriodicEvents.routeRefreshThreadLastAction = time(NULL); } else if ( (int)(difftime(desired_time,current_time_stamp)) < 2) { #ifdef DEBUG desired_tm = localtime(&desired_time); strftime(desired_time_extended, sizeof(desired_time_extended), "%Y-%m-%dT%H:%M:%SZ", desired_tm); log_warning("Session %d, Table transfer took %d seconds to proceed %d/%d indexes, desired time is %s", sessionID, (int)(difftime(desired_time,current_time_stamp)), i, session->attributeTable->tableSize, desired_time_extended ); #endif } } // end of if check //check to see if session has been shut down by another thread if(!Sessions[sessionID]){ log_msg("Session %d closed while sending its RIB!",sessionID); // send TABLE_STOP message with sessionID BMF bmf_stop = createBMF( sessionID, BMF_TYPE_TABLE_STOP); u_int32_t super_counter = htonl(xml_message_counter); bgpmonMessageAppend( bmf_stop, &super_counter, sizeof(u_int32_t) ); // include number of xml messages in bmf_stop writeQueue( labeledQueueWriter, bmf_stop); return 0; //if the session gets torn down somewhere along the line, break out of the loop because there will be no more stuff coming } if ((error = pthread_rwlock_rdlock (&(session->attributeTable->attrEntries[i].lock))) > 0) { log_err ("Failed to rdlock an entry in the rib table: %s", strerror(error)); continue; } AttrNode *node; node = session->attributeTable->attrEntries[i].node; while (node != NULL) { // send messages if (sendBMFFromAttrNode(node, session->sessionID, labeledQueueWriter) == -1) { log_err ("Failed to send BMF message for Session %d, Attribute index is %d", session->sessionID, i); } // increment number of sent XML messages xml_message_counter++; node = node->next; } pthread_rwlock_unlock(&(session->attributeTable->attrEntries[i].lock)); // count how many indexes were send index_counter++; } // end of tablesize for-loop // send TABLE_STOP message with sessionID BMF bmf_stop = createBMF( sessionID, BMF_TYPE_TABLE_STOP); u_int32_t super_counter = htonl(xml_message_counter); bgpmonMessageAppend( bmf_stop, &super_counter, sizeof(u_int32_t) ); // include number of xml messages in bmf_stop writeQueue( labeledQueueWriter, bmf_stop); // check time difference with transfer time function_end_stamp = time(NULL); #ifdef DEBUG debug(__FUNCTION__, "Diff btw finish and start functions is %d, transfer_time is %d", function_end_stamp - function_start_stamp, transfer_time); #endif if ( (function_end_stamp - function_start_stamp) > transfer_time) { log_warning("Session %d, Table transfer: Sending messages too slow!", sessionID); } else if ( (function_end_stamp - function_start_stamp) < transfer_time) { log_warning("Session %d, Table transfer: Sending messages too fast!", sessionID); } log_msg( "Successfully sent RIB table of session %d ! ", session->sessionID); return 0; }
/*---------------------------------------------------------------------------------------- * Purpose: Entry function of rib/label thread * Input: * Output: * He Yan @ Jun 22, 2008 * -------------------------------------------------------------------------------------*/ void * labelingThread( void *arg ) { log_msg( "Labeling Thread Started" ); QueueReader peerQueueReader = createQueueReader( peerQueue ); QueueWriter labeledQueueWriter = createQueueWriter( labeledQueue ); while( LabelControls.shutdown == FALSE ) { // update the last active time for this thread LabelControls.lastAction = time(NULL); BMF bmf = NULL; #ifdef DEBUG debug (__FUNCTION__, "Labeling thread waiting to read from peer queue"); #endif readQueue( peerQueueReader, (void **)&bmf ); #ifdef DEBUG debug (__FUNCTION__, "Labeling thread read from queue, processing BMF"); #endif incrementSessionMsgCount(bmf->sessionID); int action = getSessionLabelAction(bmf->sessionID); if( action >= 0) { if( action == Label || action == StoreRibOnly ) { if(processBMF( bmf )){ free(bmf); continue; } } } // delete the rib table of closed session if( bmf->type == BMF_TYPE_FSM_STATE_CHANGE ) { if( checkStateChangeMessage(bmf) ) { if( deleteRibTable(bmf->sessionID) ) log_msg( "no rib table for session %d", bmf->sessionID); else log_msg( "Successfully destroy the rib table for session %d!", bmf->sessionID); } } #ifdef DEBUG debug (__FUNCTION__, "Labeling thread processed BMF, writing to labeled queue"); #endif if( bmf->type != BMF_TYPE_TABLE_TRANSFER ) { writeQueue( labeledQueueWriter, bmf); } else { free(bmf); } #ifdef DEBUG debug (__FUNCTION__, "read from queue"); #endif // end remove for testing only } destroyQueueReader(peerQueueReader); destroyQueueWriter(labeledQueueWriter); log_warning( "Labeling thread exiting" ); return NULL; }
void CDMRSlot::writeModem(unsigned char *data) { if (data[0U] == TAG_LOST && m_state == RS_RELAYING_RF_AUDIO) { LogMessage("DMR Slot %u, transmission lost, BER: %u%%", m_slotNo, (m_errs * 100U) / m_bits); writeEndOfTransmission(); return; } if (data[0U] == TAG_LOST && m_state == RS_RELAYING_RF_DATA) { LogMessage("DMR Slot %u, transmission lost", m_slotNo); writeEndOfTransmission(); return; } if (data[0U] == TAG_LOST && m_state == RS_LATE_ENTRY) { m_state = RS_LISTENING; return; } if (m_state == RS_RELAYING_NETWORK_AUDIO || m_state == RS_RELAYING_NETWORK_DATA) return; bool dataSync = (data[1U] & DMR_SYNC_DATA) == DMR_SYNC_DATA; bool audioSync = (data[1U] & DMR_SYNC_AUDIO) == DMR_SYNC_AUDIO; if (dataSync) { CSlotType slotType; slotType.putData(data + 2U); unsigned char dataType = slotType.getDataType(); if (dataType == DT_VOICE_LC_HEADER) { if (m_state == RS_RELAYING_RF_AUDIO) return; CFullLC fullLC; m_lc = fullLC.decode(data + 2U, DT_VOICE_LC_HEADER); if (m_lc == NULL) { LogMessage("DMR Slot %u: unable to decode the LC", m_slotNo); return; } // Regenerate the Slot Type slotType.getData(data + 2U); // Convert the Data Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_DATA); data[0U] = TAG_DATA; data[1U] = 0x00U; m_networkWatchdog.stop(); m_timeoutTimer.start(); m_seqNo = 0U; m_n = 0U; m_bits = 1U; m_errs = 0U; // Put a small delay into starting retransmission writeQueue(m_idle); for (unsigned i = 0U; i < 3U; i++) { writeNetwork(data, DT_VOICE_LC_HEADER); writeQueue(data); } m_state = RS_RELAYING_RF_AUDIO; setShortLC(m_slotNo, m_lc->getDstId(), m_lc->getFLCO()); m_display->writeDMR(m_slotNo, m_lc->getSrcId(), m_lc->getFLCO() == FLCO_GROUP, m_lc->getDstId()); LogMessage("DMR Slot %u, received RF voice header from %u to %s%u", m_slotNo, m_lc->getSrcId(), m_lc->getFLCO() == FLCO_GROUP ? "TG " : "", m_lc->getDstId()); } else if (dataType == DT_VOICE_PI_HEADER) { if (m_state != RS_RELAYING_RF_AUDIO) return; // Regenerate the Slot Type slotType.getData(data + 2U); // Convert the Data Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_DATA); data[0U] = TAG_DATA; data[1U] = 0x00U; m_n = 0U; writeNetwork(data, DT_VOICE_PI_HEADER); writeQueue(data); } else if (dataType == DT_TERMINATOR_WITH_LC) { if (m_state != RS_RELAYING_RF_AUDIO) return; // Regenerate the Slot Type slotType.getData(data + 2U); // Set the Data Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_DATA); data[0U] = TAG_EOT; data[1U] = 0x00U; writeNetwork(data, DT_TERMINATOR_WITH_LC); writeQueue(data); LogMessage("DMR Slot %u, received RF end of voice transmission, BER: %u%%", m_slotNo, (m_errs * 100U) / m_bits); // 480ms of idle to space things out for (unsigned int i = 0U; i < 8U; i++) writeQueue(m_idle); writeEndOfTransmission(); } else if (dataType == DT_DATA_HEADER) { if (m_state == RS_RELAYING_RF_DATA) return; // Regenerate the Slot Type slotType.getData(data + 2U); // Convert the Data Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_DATA); data[0U] = TAG_DATA; data[1U] = 0x00U; m_networkWatchdog.stop(); m_seqNo = 0U; m_n = 0U; // Put a small delay into starting retransmission writeQueue(m_idle); for (unsigned i = 0U; i < 3U; i++) { writeNetwork(data, DT_DATA_HEADER); writeQueue(data); } m_state = RS_RELAYING_RF_DATA; // setShortLC(m_slotNo, m_lc->getDstId(), m_lc->getFLCO()); // m_display->writeDMR(m_slotNo, m_lc->getSrcId(), m_lc->getFLCO() == FLCO_GROUP, m_lc->getDstId()); // LogMessage("DMR Slot %u, received RF data header from %u to %s%u", m_slotNo, m_lc->getSrcId(), m_lc->getFLCO() == FLCO_GROUP ? "TG " : "", m_lc->getDstId()); LogMessage("DMR Slot %u, received RF data header", m_slotNo); } else { // Regenerate the Slot Type slotType.getData(data + 2U); // Convert the Data Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_DATA); data[0U] = TAG_DATA; data[1U] = 0x00U; writeNetwork(data, dataType); writeQueue(data); } } else if (audioSync) { if (m_state == RS_RELAYING_RF_AUDIO) { // Convert the Audio Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_AUDIO); unsigned char fid = m_lc->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) m_errs += m_fec.regenerateDMR(data + 2U); m_bits += 216U; data[0U] = TAG_DATA; data[1U] = 0x00U; m_n = 0U; writeQueue(data); writeNetwork(data, DT_VOICE_SYNC); } else if (m_state == RS_LISTENING) { m_state = RS_LATE_ENTRY; } } else { CEMB emb; emb.putData(data + 2U); if (m_state == RS_RELAYING_RF_AUDIO) { // Regenerate the EMB emb.setColorCode(m_colorCode); emb.getData(data + 2U); unsigned char fid = m_lc->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) m_errs += m_fec.regenerateDMR(data + 2U); m_bits += 216U; data[0U] = TAG_DATA; data[1U] = 0x00U; m_n++; writeQueue(data); writeNetwork(data, DT_VOICE); } else if (m_state == RS_LATE_ENTRY) { // If we haven't received an LC yet, then be strict on the color code unsigned char colorCode = emb.getColorCode(); if (colorCode != m_colorCode) return; m_lc = m_embeddedLC.addData(data + 2U, emb.getLCSS()); if (m_lc != NULL) { // Create a dummy start frame to replace the received frame unsigned char start[DMR_FRAME_LENGTH_BYTES + 2U]; CDMRSync sync; sync.addSync(start + 2U, DST_BS_DATA); CFullLC fullLC; fullLC.encode(*m_lc, start + 2U, DT_VOICE_LC_HEADER); CSlotType slotType; slotType.setColorCode(m_colorCode); slotType.setDataType(DT_VOICE_LC_HEADER); slotType.getData(start + 2U); start[0U] = TAG_DATA; start[1U] = 0x00U; m_networkWatchdog.stop(); m_timeoutTimer.start(); m_seqNo = 0U; m_n = 0U; m_bits = 1U; m_errs = 0U; for (unsigned int i = 0U; i < 3U; i++) { writeNetwork(start, DT_VOICE_LC_HEADER); writeQueue(start); } // Regenerate the EMB emb.getData(data + 2U); // Send the original audio frame out unsigned char fid = m_lc->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) m_errs += m_fec.regenerateDMR(data + 2U); m_bits += 216U; data[0U] = TAG_DATA; data[1U] = 0x00U; m_n++; writeQueue(data); writeNetwork(data, DT_VOICE); m_state = RS_RELAYING_RF_AUDIO; setShortLC(m_slotNo, m_lc->getDstId(), m_lc->getFLCO()); m_display->writeDMR(m_slotNo, m_lc->getSrcId(), m_lc->getFLCO() == FLCO_GROUP, m_lc->getDstId()); LogMessage("DMR Slot %u, received RF late entry from %u to %s%u", m_slotNo, m_lc->getSrcId(), m_lc->getFLCO() == FLCO_GROUP ? "TG " : "", m_lc->getDstId()); } } } }
void *weightedFairScheduler(void *pc) { pktcore_t *pcore = (pktcore_t *)pc; List *keylst; simplequeue_t *nxtq, *thisq; char *nxtkey, *savekey; double minftime, minstime, tweight; int pktsize, npktsize; gpacket_t *in_pkt, *nxt_pkt; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // die as soon as cancelled while (1) { verbose(2, "[weightedFairScheduler]:: Worst-case weighted fair queuing scheduler processing.."); pthread_mutex_lock(&(pcore->qlock)); if (pcore->packetcnt == 0) pthread_cond_wait(&(pcore->schwaiting), &(pcore->qlock)); pthread_mutex_unlock(&(pcore->qlock)); pthread_testcancel(); keylst = map_keys(pcore->queues); while (list_has_next(keylst) == 1) { nxtkey = list_next(keylst); nxtq = map_get(pcore->queues, nxtkey); if (nxtq->cursize == 0) continue; if ((nxtq->stime <= pcore->vclock) && (nxtq->ftime < minftime)) { savekey = nxtkey; minftime = nxtq->ftime; } } list_release(keylst); // if savekey is NULL then release the lock.. if (savekey == NULL) continue; else { thisq = map_get(pcore->queues, savekey); readQueue(thisq, (void **)&in_pkt, &pktsize); writeQueue(pcore->workQ, in_pkt, pktsize); pthread_mutex_lock(&(pcore->qlock)); pcore->packetcnt--; pthread_mutex_unlock(&(pcore->qlock)); peekQueue(thisq, (void **)&nxt_pkt, &npktsize); if (npktsize) { thisq->stime = thisq->ftime; thisq->ftime = thisq->stime + npktsize/thisq->weight; } minstime = thisq->stime; tweight = 0.0; keylst = map_keys(pcore->queues); while (list_has_next(keylst) == 1) { nxtkey = list_next(keylst); nxtq = map_get(pcore->queues, nxtkey); tweight += nxtq->weight; if ((nxtq->cursize > 0) && (nxtq->stime < minstime)) minstime = nxtq->stime; } list_release(keylst); pcore->vclock = max(minstime, (pcore->vclock + ((double)pktsize)/tweight)); } } }
// WCWeightFairQueuer: function called by the classifier to enqueue // the packets.. // TODO: Debug this function... int weightedFairQueuer(pktcore_t *pcore, gpacket_t *in_pkt, int pktsize, char *qkey) { simplequeue_t *thisq, *nxtq; double minftime, minstime, tweight; List *keylst; char *nxtkey, *savekey; verbose(2, "[weightedFairQueuer]:: Worst-case weighted fair queuing scheduler processing.."); pthread_mutex_lock(&(pcore->qlock)); thisq = map_get(pcore->queues, qkey); if (thisq == NULL) { fatal("[weightedFairQueuer]:: Invalid %s key presented for queue addition", qkey); pthread_mutex_unlock(&(pcore->qlock)); return EXIT_FAILURE; // packet dropped.. } printf("Checking the queue size \n"); if (thisq->cursize == 0) { verbose(2, "[weightedFairQueuer]:: inserting the first element.. "); thisq->stime = max(pcore->vclock, thisq->ftime); thisq->ftime = thisq->stime + pktsize/thisq->weight; minstime = thisq->stime; keylst = map_keys(pcore->queues); while (list_has_next(keylst) == 1) { nxtkey = list_next(keylst); nxtq = map_get(pcore->queues, nxtkey); if ((nxtq->cursize > 0) && (nxtq->stime < minstime)) minstime = nxtq->stime; } list_release(keylst); pcore->vclock = max(minstime, pcore->vclock); // insert the packet... and increment variables.. writeQueue(thisq, in_pkt, pktsize); pcore->packetcnt++; // wake up scheduler if it was waiting.. if (pcore->packetcnt == 1) pthread_cond_signal(&(pcore->schwaiting)); pthread_mutex_unlock(&(pcore->qlock)); return EXIT_SUCCESS; } else if (thisq->cursize < thisq->maxsize) { // insert packet and setup variables.. writeQueue(thisq, in_pkt, pktsize); pcore->packetcnt++; pthread_mutex_unlock(&(pcore->qlock)); return EXIT_SUCCESS; } else { verbose(2, "[weightedFairQueuer]:: Packet dropped.. Queue for %s is full ", qkey); pthread_mutex_unlock(&(pcore->qlock)); return EXIT_SUCCESS; } }
void *weightedFairScheduler(void *pc) { pktcore_t *pcore = (pktcore_t *)pc; List *keylst; simplequeue_t *nxtq, *thisq; char *nxtkey, *savekey; double minftime, minstime, tweight; int pktsize, npktsize; gpacket_t *in_pkt, *nxt_pkt; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // die as soon as cancelled //MOD pcore->vclock = 0.0; //pktsize - used to get the packet size of packet being enqueued now //npktsize - used to determine if there are more packets in current queue // while (1) { verbose(2, "[weightedFairScheduler]:: Worst-case weighted fair queuing scheduler processing.."); pthread_mutex_lock(&(pcore->qlock)); if (pcore->packetcnt == 0) pthread_cond_wait(&(pcore->schwaiting), &(pcore->qlock)); pthread_mutex_unlock(&(pcore->qlock)); pthread_testcancel(); keylst = map_keys(pcore->queues); minftime = MAX_DOUBLE;//MOD savekey = NULL;//MOD while (list_has_next(keylst) == 1) { nxtkey = list_next(keylst); nxtq = map_get(pcore->queues, nxtkey); if (nxtq->cursize == 0) continue; //determines the minftime if ((nxtq->stime <= pcore->vclock) && (nxtq->ftime < minftime)) { savekey = nxtkey; minftime = nxtq->ftime; } } list_release(keylst); // if savekey is NULL then release the lock.. if (savekey == NULL) continue; else { thisq = map_get(pcore->queues, savekey); readQueue(thisq, (void **)&in_pkt, &pktsize); writeQueue(pcore->workQ, in_pkt, pktsize); pthread_mutex_lock(&(pcore->qlock)); pcore->packetcnt--; pthread_mutex_unlock(&(pcore->qlock)); peekQueue(thisq, (void **)&nxt_pkt, &npktsize); //Doing this because we don't change the stime and //ftime unless a new packet comes into an empty queue if (npktsize) { thisq->stime = thisq->ftime; thisq->ftime = thisq->stime + npktsize/thisq->weight; } minstime = thisq->stime; tweight = 0.0; keylst = map_keys(pcore->queues); //determine minstime while (list_has_next(keylst) == 1) { nxtkey = list_next(keylst); nxtq = map_get(pcore->queues, nxtkey); tweight += nxtq->weight; if ((nxtq->cursize > 0) && (nxtq->stime < minstime)) minstime = nxtq->stime; } list_release(keylst); pcore->vclock = max(minstime, (pcore->vclock + ((double)pktsize)/tweight)); } } }
int main(int argc, char **argv) { char program_name[FILENAME_MAX_CHARS]; char config_file[FILENAME_MAX_CHARS]; int syslog; int loglevel; int logfacility; char c; int recoveryport; int error; int daemon_mode = 0; // init program_name and default config file strncpy(program_name, argv[0], FILENAME_MAX_CHARS); strncpy(config_file, DEFAULT_CONFIGFILE, FILENAME_MAX_CHARS); // init default log settings syslog = DEFAULT_USE_SYSLOG; loglevel = DEFAULT_LOG_LEVEL; logfacility = DEFAULT_LOG_FACILITY; // allow the user to set a special port for login recovery recoveryport = 0; //save start time for uptime calculation in status messages bgpmon_start_time = time(NULL); // parse command line while ((c = getopt (argc, argv, "dl:c:f:hsr:")) != -1) { switch (c) { case 'c': strncpy(config_file, optarg, FILENAME_MAX_CHARS); break; case 'l': loglevel = atoi(optarg); break; case 'f': logfacility = atoi(optarg); break; case 's': syslog = 1; break; case 'r': recoveryport = atoi(optarg); break; case 'd': daemon_mode = 1; break; case 'h': case '?': default : usage( argv[0] ); break; } } // if optind is less than the number of arguments from the command line (argc), then there // is something in the argument string that isn't preceded by valid switch (-c, -l, etc) if(optind<argc) { usage(argv[0]); } // initilaze log module if (init_log (program_name, syslog, loglevel, logfacility) ) { fprintf (stderr, "Failed to initialize log functions!\n"); exit(1); } #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized log module."); #endif log_msg("BGPmon starting up\n"); /* Turn into daemon if daemon_mode is set. */ if (daemon_mode){ godaemon(RUN_DIR,PID_FILE); } char scratchdir[FILENAME_MAX_CHARS]; sprintf(scratchdir,"%s/%s",RUN_DIR,"bgpmon"); // initialize login interface if (initLoginControlSettings(config_file, scratchdir, recoveryport) ) { log_fatal("Unable to initialize login interface"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized login module."); #endif // initialize acl if(initACLSettings()) { log_fatal("Unable to initialize ACL settings"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized acl module."); #endif // initialize the queue information if (initQueueSettings() ) { log_fatal("Unable to initialize queue settings"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized queue settings."); #endif // initialize clients control settings if (initClientsControlSettings() ) { log_fatal("Unable to initialize client settings"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized client settings."); #endif // initialize clients control settings if (initMrtControlSettings() ) { log_fatal("Unable to initialize mrt settings"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized mrt settings."); #endif // initialize chains settings if (initChainsSettings() ) { log_fatal("Unable to initialize chain settings"); }; // initialize the periodic settings if (initPeriodicSettings() ) { log_fatal("Unable to initialize periodic settings"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized periodic settings."); #endif // read in the configuration file and change // all relevant settings based on config file if (readConfigFile(config_file) ) { // if the configuration file is not readable, remove the // configuration file and backup a copy backupConfigFile(LoginSettings.configFile, LoginSettings.scratchDir); saveConfigFile(LoginSettings.configFile); log_err("Corrupt Configuration File Moved to %s. New configuration file written.", LoginSettings.scratchDir); } /* * Block signals in initial thread. New threads will * inherit this signal mask. All the signals will be handled * in a dedicated thread */ sigfillset ( &signalSet ); pthread_sigmask ( SIG_BLOCK, &signalSet, NULL ); // launch the signal handling thread #ifdef DEBUG debug(__FUNCTION__, "Creating signal thread..."); #endif pthread_t sighandlerThreadID; if ((error = pthread_create(&sighandlerThreadID, NULL, sigHandler, config_file)) > 0 ) log_fatal("Failed to create signal handler thread: %s\n", strerror(error)); #ifdef DEBUG debug(__FUNCTION__, "Created signal thread!"); #endif // create the system queues #ifdef DEBUG debug(__FUNCTION__, "Creating queues..."); #endif /*create the peer queue*/ peerQueue = createQueue(copyBMF, sizeOfBMF, PEER_QUEUE_NAME, strlen(PEER_QUEUE_NAME), FALSE); /*create the label queue*/ labeledQueue = createQueue(copyBMF, sizeOfBMF, LABEL_QUEUE_NAME, strlen(LABEL_QUEUE_NAME), FALSE); /*create the xml queue*/ xmlUQueue = createQueue(copyXML, sizeOfXML, XML_U_QUEUE_NAME, strlen(XML_U_QUEUE_NAME), TRUE); xmlRQueue = createQueue(copyXML, sizeOfXML, XML_R_QUEUE_NAME, strlen(XML_R_QUEUE_NAME), TRUE); #ifdef DEBUG debug(__FUNCTION__, "Created queues!"); #endif // launch the peering thread #ifdef DEBUG debug(__FUNCTION__, "Creating peering thread..."); #endif launchAllPeers(); #ifdef DEBUG debug(__FUNCTION__, "Created peering thread!"); #endif // launch the labeling thread #ifdef DEBUG debug(__FUNCTION__, "Creating labeling thread..."); #endif launchLabelingThread(); #ifdef DEBUG debug(__FUNCTION__, "Created labeling thread!"); #endif // launch the xml thread #ifdef DEBUG debug(__FUNCTION__, "Creating xml thread..."); #endif launchXMLThread(); #ifdef DEBUG debug(__FUNCTION__, "Created xml thread!"); #endif // launch the clients control thread #ifdef DEBUG debug(__FUNCTION__, "Creating clients control thread..."); #endif launchClientsControlThread(); #ifdef DEBUG debug(__FUNCTION__, "Created clients control thread!"); #endif // launch the mrt control thread #ifdef DEBUG debug(__FUNCTION__, "Creating mrt control thread..."); #endif launchMrtControlThread(); #ifdef DEBUG debug(__FUNCTION__, "Created mrt control thread!"); #endif // launch the configured chains thread #ifdef DEBUG debug(__FUNCTION__, "Creating threads for each configured chain..."); #endif launchAllChainsThreads(); #ifdef DEBUG debug(__FUNCTION__, "Created threads for each configured chain!"); #endif // launch the login thread #ifdef DEBUG debug(__FUNCTION__, "Creating login thread..."); #endif launchLoginControlThread(); #ifdef DEBUG debug(__FUNCTION__, "Created login thread!"); #endif // launch the periodic thread #ifdef DEBUG debug(__FUNCTION__, "Creating periodic thread..."); #endif LaunchPeriodicThreads(); #ifdef DEBUG debug(__FUNCTION__, "Created periodic thread!"); #endif // write BGPMON_START message into the Peer Queue BMF bmf = createBMF(0, BMF_TYPE_BGPMON_START); QueueWriter qw = createQueueWriter(peerQueue); writeQueue(qw, bmf); destroyQueueWriter(qw); // periodically check on the state of each thread time_t threadtime; time_t currenttime; char currenttime_extended[64]; memset(currenttime_extended, 0, 64); char threadtime_extended[64]; memset(threadtime_extended, 0, 64); struct tm * current_tm = NULL; struct tm * thread_tm = NULL; int *chainIDs; long *clientIDs; long *mrtIDs; int clientcount, chaincount, mrtcount, i; while ( TRUE ) { // get the current running time to compare the threads // last exection time to currenttime = time(NULL); sleep(THREAD_CHECK_INTERVAL); current_tm = localtime(¤ttime); strftime(currenttime_extended, sizeof(currenttime_extended), "%Y-%m-%dT%H:%M:%SZ", current_tm); // CLI MODULE // check the cli listener threadtime = getLoginControlLastAction(); if (difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("CLI Module is idle: current time = %s, last thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // check the individual cli threads for updates int clicount = 0; long * cliIDs = NULL; clicount = getActiveCliIds(&cliIDs); if(clicount != -1) { for ( i=0; i<clicount; i++) { threadtime = getCliLastAction(cliIDs[i]); if ( difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Cli %d is idle: current time = %s, last cli %d thread time = %s", cliIDs[i], currenttime_extended, cliIDs[i], threadtime_extended); } } free(cliIDs); } // CLIENTS MODULE // Clients Module threadtime = getClientsControlLastAction(); thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); if (difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Clients Module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // UPDATE clients clientcount = getActiveClientsIDs(&clientIDs, CLIENT_LISTENER_UPDATA); if(clientcount != -1) { for (i = 0; i < clientcount; i++) { threadtime = getClientLastAction(clientIDs[i], CLIENT_LISTENER_UPDATA); if (difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Updates Client %d is idle: current time = %s, last client %d thread time = %s", clientIDs[i], currenttime_extended, clientIDs[i], threadtime_extended); } } free(clientIDs); } // RIB clients clientcount = getActiveClientsIDs(&clientIDs, CLIENT_LISTENER_RIB); if(clientcount != -1) { for (i = 0; i < clientcount; i++) { threadtime = getClientLastAction(clientIDs[i], CLIENT_LISTENER_RIB); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("RIB Client %d is idle: current time = %s, last client %d thread time = %s", clientIDs[i], currenttime_extended, clientIDs[i], threadtime_extended); } } free(clientIDs); } // PEER MODULE for (i=0; i < MAX_SESSION_IDS; i++) { if( Sessions[i] != NULL && getSessionState(Sessions[i]->sessionID) == stateEstablished) { threadtime = getSessionLastActionTime(i); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Peering session %d is idle: current time = %s, last client %d thread time = %s",Sessions[i]->sessionID, currenttime_extended, Sessions[i]->sessionID, threadtime_extended); //closeBgpmon(config_file); } } } // LABELING MODULE threadtime = getLabelThreadLastActionTime(); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Labeling module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // XML MODULE threadtime = getXMLThreadLastAction(); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("XML module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // QUAGGA MODULE // mrt listener threadtime = getMrtControlLastAction(); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("MRT module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // mrt connections mrtcount = getActiveMrtsIDs(&mrtIDs); if(mrtcount != -1) { for (i = 0; i < mrtcount; i++) { threadtime = getMrtLastAction(mrtIDs[i]); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("MRT client %d is idle: current time = %s, last client %d thread time = %s",mrtIDs[i], currenttime_extended, mrtIDs[i], threadtime_extended); } } free(mrtIDs); } // CHAIN MODULE chaincount = getActiveChainsIDs(&chainIDs); if(chaincount != -1) { for (i = 0; i < chaincount; i++) { threadtime = getChainLastAction(chainIDs[i]); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("BGPmon chain %ld is idle: current time = %s, last client %ld thread time = %s", chainIDs[i], currenttime_extended, chainIDs[i], threadtime_extended); } } free(chainIDs); } // PERIODIC MODULE // route refresh threadtime = getPeriodicRouteRefreshThreadLastActionTime(); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Route Refresh module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // status message threadtime = getPeriodicStatusMessageThreadLastActionTime(); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Status Messages module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } } // should never get here log_err( "main: unexpectedly finished"); return(0); }
void* process_packet(void * args) { struct arguments *args_ptr = (struct arguments *) args; struct flowentry* flowtable = (struct flowentry*) args_ptr->flowtable; int flowtableSize = 0; while (1) { int count = -1; if (queue1->cursize > 0) { gpacket_t *data; int len, i=0; readQueue(queue1, (void**) &data, &len); gpacket_t *temp_gpacket = data; pkt_data_t temp_data_packet = temp_gpacket->data; pkt_frame_t iface = temp_gpacket->frame; ip_packet_t *ip_pkt; ip_pkt = (ip_packet_t *) temp_data_packet.data; /* printf("\nFOUND THE PACKET::\n"); printf("\nip_src: %d", ip_pkt->ip_src[0]); printf("\nip_src: %d", ip_pkt->ip_src[1]); printf("\nip_src: %d", ip_pkt->ip_src[2]); printf("\nip_src: %d", ip_pkt->ip_src[3]); printf("\nip_dest: %d", ip_pkt->ip_dst[0]); printf("\nip_dest: %d", ip_pkt->ip_dst[1]); printf("\nip_dest: %d", ip_pkt->ip_dst[2]); printf("\nip_dest: %d", ip_pkt->ip_dst[3]); printf("\nip_prot: %d", ip_pkt->ip_prot); printf("\ndata_packet: %d", temp_data_packet.header.prot); printf("\ndata_packet: %d", temp_data_packet.header.dst[0]); printf("\ndata_packet: %d", temp_data_packet.header.dst[1]); printf("\ndata_packet: %d", temp_data_packet.header.dst[2]); printf("\ndata_packet: %d", temp_data_packet.header.dst[3]); printf("\ndata_packet: %d", temp_data_packet.header.dst[4]); printf("\ndata_packet: %d", temp_data_packet.header.dst[5]); printf("\nSrc: %d", temp_data_packet.header.src[0]); printf("\nSrc: %d", temp_data_packet.header.src[1]); printf("\nSrc: %d", temp_data_packet.header.src[2]); printf("\nSrc: %d", temp_data_packet.header.src[3]); printf("\nSrc: %d", temp_data_packet.header.src[4]); printf("\nSrc: %d", temp_data_packet.header.src[5]);*/ //Comparison logic bool match_found = FALSE; /* printf("\nPRINTING FLOW TABLE "); for(i=0; i<flowtableSize; i++){ printf("\n %d %d %d %d %d %d\n", flowtable[i].match.hw_addr_src[0],flowtable[i].match.hw_addr_src[1],flowtable[i].match.hw_addr_src[2],flowtable[i].match.hw_addr_src[3],flowtable[i].match.hw_addr_src[4],flowtable[i].match.hw_addr_src[5]); printf("\n %d %d %d %d %d %d\n", flowtable[i].match.hw_addr_dest[0],flowtable[i].match.hw_addr_dest[1],flowtable[i].match.hw_addr_dest[2],flowtable[i].match.hw_addr_dest[3],flowtable[i].match.hw_addr_dest[4],flowtable[i].match.hw_addr_dest[5]); }*/ //printf("\nFlowtable size is: %d",flowtableSize); while (flowtableSize > 0 && ++count < flowtableSize && flowtable[count].match.protocol != 0 && flowtable[count].match.ip_addr_src[0] != 0) { // Check for end of flowtable entries /*if (flowtable[count].match.protocol != temp_data_packet.header.prot) continue;*/ //printf("\nCheckpoint 1\n"); if (flowtable[count].match.hw_addr_src[0] != temp_data_packet.header.dst[0]) continue; //printf("\nCheckpoint 2\n"); if (flowtable[count].match.hw_addr_src[1] != temp_data_packet.header.dst[1]) continue; //printf("\nCheckpoint 3\n"); if (flowtable[count].match.hw_addr_src[2] != temp_data_packet.header.dst[2]) continue; // printf("\nCheckpoint 4\n"); if (flowtable[count].match.hw_addr_src[3] != temp_data_packet.header.dst[3]) continue; // printf("\nCheckpoint 5\n"); if (flowtable[count].match.hw_addr_src[4] != temp_data_packet.header.dst[4]) continue; // printf("\nCheckpoint 6\n"); if (flowtable[count].match.hw_addr_src[5] != temp_data_packet.header.dst[5]) continue; // printf("\nCheckpoint 7\n"); /* if (flowtable[count].match.ip_protocol != ip_pkt->ip_prot) continue; printf("\nCheckpoint 8\n");*/ if (flowtable[count].match.ip_tos != ip_pkt->ip_tos) continue; // printf("\nCheckpoint 9\n"); if (flowtable[count].match.ip_addr_src[0] != ip_pkt->ip_src[0]) continue; // printf("\nCheckpoint 10\n"); if (flowtable[count].match.ip_addr_src[1] != ip_pkt->ip_src[1]) continue; // printf("\nCheckpoint 11\n"); if (flowtable[count].match.ip_addr_src[2] != ip_pkt->ip_src[2]) continue; // printf("\nCheckpoint 12\n"); if (flowtable[count].match.ip_addr_src[3] != ip_pkt->ip_src[3]) continue; // printf("\nCheckpoint 13\n"); if (flowtable[count].match.ip_addr_dest[0] != ip_pkt->ip_dst[0]) continue; // printf("\nCheckpoint 14\n"); if (flowtable[count].match.ip_addr_dest[1] != ip_pkt->ip_dst[1]) continue; // printf("\nCheckpoint 15\n"); if (flowtable[count].match.ip_addr_dest[2] != ip_pkt->ip_dst[2]) continue; // printf("\nCheckpoint 16\n"); if (flowtable[count].match.ip_addr_dest[3] != ip_pkt->ip_dst[3]) continue; // printf("\nCheckpoint 17\n"); match_found = TRUE; if(flowtable[count].action == 0){ printf("\nPacket Dropped!!\n\n"); break; } temp_gpacket->frame.dst_interface = flowtable[count].action; // printf("\n Outgoing Interface is: %d \n", temp_gpacket->frame.dst_interface); temp_data_packet.header.src[0] = temp_data_packet.header.dst[0]; temp_data_packet.header.src[1] = temp_data_packet.header.dst[1]; temp_data_packet.header.src[2] = temp_data_packet.header.dst[2]; temp_data_packet.header.src[3] = temp_data_packet.header.dst[3]; temp_data_packet.header.src[4] = temp_data_packet.header.dst[4]; temp_data_packet.header.src[5] = temp_data_packet.header.dst[5]; temp_gpacket->data.header.dst[0] = flowtable[count].match.hw_addr_dest[0]; temp_gpacket->data.header.dst[1] = flowtable[count].match.hw_addr_dest[1]; temp_gpacket->data.header.dst[2] = flowtable[count].match.hw_addr_dest[2]; temp_gpacket->data.header.dst[3] = flowtable[count].match.hw_addr_dest[3]; temp_gpacket->data.header.dst[4] = flowtable[count].match.hw_addr_dest[4]; temp_gpacket->data.header.dst[5] = flowtable[count].match.hw_addr_dest[5]; if(temp_gpacket->data.header.dst[0] == 255 && temp_gpacket->data.header.dst[1] == 255 && temp_gpacket->data.header.dst[2] == 255 && temp_gpacket->data.header.dst[3] == 255 && temp_gpacket->data.header.dst[4] == 255 && temp_gpacket->data.header.dst[5] == 255){ printf("\nBroadcasing Packet!!\n"); /* ip_packet_t *ip_pkt_new; ip_pkt_new = (ip_packet_t *) temp_gpacket->data.data; ip_pkt_new->ip_src[3] = ip_pkt_new->ip_src[1]; ip_pkt_new->ip_src[1] = ip_pkt_new->ip_src[2]; ip_pkt_new->ip_src[2] = ip_pkt_new->ip_src[0]; ip_pkt_new->ip_src[0] = 0; ip_pkt_new->ip_dst[0] = ip_pkt_new->ip_src[2]; ip_pkt_new->ip_dst[1] = 130; ip_pkt_new->ip_dst[2] = 255; ip_pkt_new->ip_dst[3] = 255; temp_gpacket->frame.nxth_ip_addr[0] = 0; temp_gpacket->frame.nxth_ip_addr[1] = 5; temp_gpacket->frame.nxth_ip_addr[2] = 168; temp_gpacket->frame.nxth_ip_addr[3] = 192; temp_gpacket->frame.arp_bcast = 1; temp_gpacket->data.header.prot = 1544; ip_pkt_new->ip_prot = 253; ip_pkt_new->ip_tos = 1; ip_pkt_new->ip_frag_off = 256; ip_pkt_new->ip_hdr_len = 0; ip_pkt_new->ip_identifier = 1030; ip_pkt_new->ip_pkt_len = 8; ip_pkt_new->ip_version = 0; printf("\nip_cksum: %d\n",ip_pkt->ip_cksum); printf("\nip_frag_off: %d\n",ip_pkt->ip_frag_off); printf("\nip_hdr_len: %d\n",ip_pkt->ip_hdr_len); printf("\nip_identifier: %d\n",ip_pkt->ip_identifier); printf("\nip_pkt_len: %d\n",ip_pkt->ip_pkt_len); printf("\nip_ttl: %d\n",ip_pkt->ip_ttl); printf("\nip_version: %d\n",ip_pkt->ip_version);*/ } /* if (flowtable[count].action == FORWARD_ALL) { //TODO:Replicate packet for all outgoing ports and place packets in output_queue } if (flowtable[count].action == FORWARD_TO_DESTINATION) { temp_gpacket->frame.dst_interface = flowtable[count].port_number; printf("\nMATCH FOUND. ADDING PACKET IN OutputQ\n"); writeQueue(outputQ, (void *) temp_gpacket, sizeof(gpacket_t)); } if (flowtable[count].action == FORWARD_CONTROLLER) { } if (flowtable[count].action == DROP) { free(temp_gpacket); }*/ //TODO:update counters writeQueue(outputQ, (void *) temp_gpacket, sizeof(gpacket_t)); break; } if ((match_found == FALSE || flowtableSize == 0) && ip_pkt->ip_tos == 0 && ip_pkt->ip_prot == 1) { struct message query; query.src_mac[0] = temp_data_packet.header.dst[0]; query.src_mac[1] = temp_data_packet.header.dst[1]; query.src_mac[2] = temp_data_packet.header.dst[2]; query.src_mac[3] = temp_data_packet.header.dst[3]; query.src_mac[4] = temp_data_packet.header.dst[4]; query.src_mac[5] = temp_data_packet.header.dst[5]; query.src_ip[0] = ip_pkt->ip_src[0]; query.src_ip[1] = ip_pkt->ip_src[1]; query.src_ip[2] = ip_pkt->ip_src[2]; query.src_ip[3] = ip_pkt->ip_src[3]; query.dest_ip[0] = ip_pkt->ip_dst[0]; query.dest_ip[1] = ip_pkt->ip_dst[1]; query.dest_ip[2] = ip_pkt->ip_dst[2]; query.dest_ip[3] = ip_pkt->ip_dst[3]; query.protocol = ip_pkt->ip_prot; query.tos = ip_pkt->ip_tos; struct reply* response = callServerToFindInterface(&query); flowtable[flowtableSize].match.hw_addr_src[0] = query.src_mac[0]; flowtable[flowtableSize].match.hw_addr_src[1] = query.src_mac[1]; flowtable[flowtableSize].match.hw_addr_src[2] = query.src_mac[2]; flowtable[flowtableSize].match.hw_addr_src[3] = query.src_mac[3]; flowtable[flowtableSize].match.hw_addr_src[4] = query.src_mac[4]; flowtable[flowtableSize].match.hw_addr_src[5] = query.src_mac[5]; flowtable[flowtableSize].match.hw_addr_dest[0] = response->dest_mac[0]; flowtable[flowtableSize].match.hw_addr_dest[1] = response->dest_mac[1]; flowtable[flowtableSize].match.hw_addr_dest[2] = response->dest_mac[2]; flowtable[flowtableSize].match.hw_addr_dest[3] = response->dest_mac[3]; flowtable[flowtableSize].match.hw_addr_dest[4] = response->dest_mac[4]; flowtable[flowtableSize].match.hw_addr_dest[5] = response->dest_mac[5]; flowtable[flowtableSize].match.ip_addr_src[0] = ip_pkt->ip_src[0]; flowtable[flowtableSize].match.ip_addr_src[1] = ip_pkt->ip_src[1]; flowtable[flowtableSize].match.ip_addr_src[2] = ip_pkt->ip_src[2]; flowtable[flowtableSize].match.ip_addr_src[3] = ip_pkt->ip_src[3]; flowtable[flowtableSize].match.ip_addr_dest[0] = ip_pkt->ip_dst[0]; flowtable[flowtableSize].match.ip_addr_dest[1] = ip_pkt->ip_dst[1]; flowtable[flowtableSize].match.ip_addr_dest[2] = ip_pkt->ip_dst[2]; flowtable[flowtableSize].match.ip_addr_dest[3] = ip_pkt->ip_dst[3]; flowtable[flowtableSize].match.protocol = ip_pkt->ip_prot; flowtable[flowtableSize].match.ip_tos = ip_pkt->ip_tos; flowtable[flowtableSize].action = response->interface; flowtableSize++; temp_gpacket->frame.dst_interface = response->interface; temp_data_packet.header.src[0] = temp_data_packet.header.dst[0]; temp_data_packet.header.src[1] = temp_data_packet.header.dst[1]; temp_data_packet.header.src[2] = temp_data_packet.header.dst[2]; temp_data_packet.header.src[3] = temp_data_packet.header.dst[3]; temp_data_packet.header.src[4] = temp_data_packet.header.dst[4]; temp_data_packet.header.src[5] = temp_data_packet.header.dst[5]; temp_gpacket->data.header.dst[0] = response->dest_mac[0]; temp_gpacket->data.header.dst[1] = response->dest_mac[1]; temp_gpacket->data.header.dst[2] = response->dest_mac[2]; temp_gpacket->data.header.dst[3] = response->dest_mac[3]; temp_gpacket->data.header.dst[4] = response->dest_mac[4]; temp_gpacket->data.header.dst[5] = response->dest_mac[5]; //printf("\nMATCH NOT FOUND. ADDING PACKET IN QUEUE2\n"); //writeQueue(queue2, (void *)temp_gpacket, sizeof(gpacket_t)); writeQueue(outputQ, (void *) temp_gpacket, sizeof(gpacket_t)); } ////////////////////////// //Comparision logic //logic for placing packet in queue2 } } return 0; }
/* * TODO: Some form of conformance check so that only packets * destined to the particular Ethernet protocol are being captured * by the handler... right now.. this might capture other packets as well. */ void* fromEthernetDev(void *arg) { interface_t *iface = (interface_t *) arg; interface_array_t *iarr = (interface_array_t *)iface->iarray; uchar bcast_mac[] = MAC_BCAST_ADDR; gpacket_t *in_pkt; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // die as soon as cancelled while (1) { verbose(2, "[fromEthernetDev]:: Receiving a packet ..."); if ((in_pkt = (gpacket_t *)malloc(sizeof(gpacket_t))) == NULL) { fatal("[fromEthernetDev]:: unable to allocate memory for packet.. "); return NULL; } bzero(in_pkt, sizeof(gpacket_t)); vpl_recvfrom(iface->vpl_data, &(in_pkt->data), sizeof(pkt_data_t)); pthread_testcancel(); // check whether the incoming packet is a layer 2 broadcast or // meant for this node... otherwise should be thrown.. // TODO: fix for promiscuous mode packet snooping. if ((COMPARE_MAC(in_pkt->data.header.dst, iface->mac_addr) != 0) && (COMPARE_MAC(in_pkt->data.header.dst, bcast_mac) != 0)) { verbose(1, "[fromEthernetDev]:: Packet dropped .. not for this router!? "); free(in_pkt); continue; } // copy fields into the message from the packet.. in_pkt->frame.src_interface = iface->interface_id; COPY_MAC(in_pkt->frame.src_hw_addr, iface->mac_addr); COPY_IP(in_pkt->frame.src_ip_addr, iface->ip_addr); //Printing packet values /* printf("\n=========== INCOMING PACKET VALUES ================\n"); printf("\n----------HEADER VALUES :"); printf("\nSource MAC Address: %x : %x : %x : %x : %x : %x", in_pkt->data.header.src[0], in_pkt->data.header.src[1],in_pkt->data.header.src[2], in_pkt->data.header.src[3],in_pkt->data.header.src[4],in_pkt->data.header.src[5]); printf("\nDestination MAC Address: %x : %x : %x : %x : %x : %x", in_pkt->data.header.dst[0], in_pkt->data.header.dst[1],in_pkt->data.header.dst[2], in_pkt->data.header.dst[3],in_pkt->data.header.dst[4],in_pkt->data.header.dst[5]); printf("\nSource IP Address: %d.%d.%d.%d", in_pkt->frame.src_ip_addr[0], in_pkt->frame.src_ip_addr[1],in_pkt->frame.src_ip_addr[2], in_pkt->frame.src_ip_addr[3]); printf("\nProtocol is : %d",in_pkt->data.header.prot); printf("\nDestination Interface is : %d",in_pkt->frame.dst_interface); printf("\nIngress Port is : %d",in_pkt->frame.src_interface); printf("\nNXTH IP Destination: %d.%d.%d.%d", in_pkt->frame.nxth_ip_addr[0],in_pkt->frame.nxth_ip_addr[1], in_pkt->frame.nxth_ip_addr[2],in_pkt->frame.nxth_ip_addr[3]); printf("\n --- IP PACKET:"); ip_packet_t *ip_pkt; ip_pkt = (ip_packet_t *) in_pkt->data.data; printf("\nIP Source: %d.%d.%d.%d", ip_pkt->ip_src[0],ip_pkt->ip_src[1],ip_pkt->ip_src[2],ip_pkt->ip_src[3]); printf("\nIP Destination: %d.%d.%d.%d", ip_pkt->ip_dst[0],ip_pkt->ip_dst[1],ip_pkt->ip_dst[2],ip_pkt->ip_dst[3]); printf("\nIP Protocol is : %d",ip_pkt->ip_prot); printf("\nIP TOS: %d\n",ip_pkt->ip_tos);*/ // check for filtering.. if the it should be filtered.. then drop if (filteredPacket(filter, in_pkt)) { verbose(2, "[fromEthernetDev]:: Packet filtered..!"); free(in_pkt); continue; // skip the rest of the loop } verbose(2, "[fromEthernetDev]:: Packet is sent for enqueuing.."); //ENQUEUE PACKET TO QUEUE_1 if (in_pkt->data.header.prot == htons(ARP_PROTOCOL)) { ARPProcess(in_pkt); } else{ /* if(in_pkt->frame.src_interface == 1){ printf("\n RECEIVED PACKET FROM INTERFACE 1"); in_pkt->frame.dst_interface = 2; // HATA DO MUJHE in_pkt->data.header.src[0] = in_pkt->data.header.dst[0]; in_pkt->data.header.src[1] = in_pkt->data.header.dst[1]; in_pkt->data.header.src[2] = in_pkt->data.header.dst[2]; in_pkt->data.header.src[3] = in_pkt->data.header.dst[3]; in_pkt->data.header.src[4] = in_pkt->data.header.dst[4]; in_pkt->data.header.src[5] = in_pkt->data.header.dst[5]; in_pkt->data.header.dst[0] = 254; in_pkt->data.header.dst[1] = 253; in_pkt->data.header.dst[2] = 2; in_pkt->data.header.dst[3] = 0; in_pkt->data.header.dst[4] = 0; in_pkt->data.header.dst[5] = 1; in_pkt->data.header.src[0] = 254; in_pkt->data.header.src[1] = 253; in_pkt->data.header.src[2] = 3; in_pkt->data.header.src[3] = 01; in_pkt->data.header.src[4] = 0; in_pkt->data.header.src[5] = 2; } else if(in_pkt->frame.src_interface == 2){ printf("\n RECEIVED PACKET FROM INTERFACE 2"); in_pkt->frame.dst_interface = 1; in_pkt->data.header.src[0] = in_pkt->data.header.dst[0]; in_pkt->data.header.src[1] = in_pkt->data.header.dst[1]; in_pkt->data.header.src[2] = in_pkt->data.header.dst[2]; in_pkt->data.header.src[3] = in_pkt->data.header.dst[3]; in_pkt->data.header.src[4] = in_pkt->data.header.dst[4]; in_pkt->data.header.src[5] = in_pkt->data.header.dst[5]; in_pkt->data.header.dst[0] = 254; in_pkt->data.header.dst[1] = 253; in_pkt->data.header.dst[2] = 2; in_pkt->data.header.dst[3] = 0; in_pkt->data.header.dst[4] = 0; in_pkt->data.header.dst[5] = 2; in_pkt->data.header.src[0] = 254; in_pkt->data.header.src[1] = 253; in_pkt->data.header.src[2] = 03; in_pkt->data.header.src[3] = 01; in_pkt->data.header.src[4] = 0; in_pkt->data.header.src[5] = 1; }*/ writeQueue(queue1, (void *)in_pkt, sizeof(gpacket_t)); } } }
void CDMRSlot::writeNetwork(const CDMRData& dmrData) { if (m_state == RS_RELAYING_RF_AUDIO || m_state == RS_RELAYING_RF_DATA || m_state == RS_LATE_ENTRY) return; m_networkWatchdog.start(); unsigned char dataType = dmrData.getDataType(); unsigned char data[DMR_FRAME_LENGTH_BYTES + 2U]; dmrData.getData(data + 2U); if (dataType == DT_VOICE_LC_HEADER) { if (m_state == RS_RELAYING_NETWORK_AUDIO) return; CFullLC fullLC; m_lc = fullLC.decode(data + 2U, DT_VOICE_LC_HEADER); if (m_lc == NULL) { LogMessage("DMR Slot %u, bad LC received from the network", m_slotNo); return; } // Regenerate the Slot Type CSlotType slotType; slotType.setColorCode(m_colorCode); slotType.setDataType(DT_VOICE_LC_HEADER); slotType.getData(data + 2U); // Convert the Data Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_DATA); data[0U] = TAG_DATA; data[1U] = 0x00U; m_timeoutTimer.start(); m_frames = 0U; m_bits = 1U; m_errs = 0U; // 540ms of idle to give breathing space for lost frames for (unsigned int i = 0U; i < 9U; i++) writeQueue(m_idle); for (unsigned int i = 0U; i < 3U; i++) writeQueue(data); m_state = RS_RELAYING_NETWORK_AUDIO; setShortLC(m_slotNo, m_lc->getDstId(), m_lc->getFLCO()); m_display->writeDMR(m_slotNo, m_lc->getSrcId(), m_lc->getFLCO() == FLCO_GROUP, m_lc->getDstId()); #if defined(DUMP_DMR) openFile(); writeFile(data); #endif LogMessage("DMR Slot %u, received network voice header from %u to %s%u", m_slotNo, m_lc->getSrcId(), m_lc->getFLCO() == FLCO_GROUP ? "TG " : "", m_lc->getDstId()); } else if (dataType == DT_VOICE_PI_HEADER) { if (m_state != RS_RELAYING_NETWORK_AUDIO) return; // Regenerate the Slot Type CSlotType slotType; slotType.setColorCode(m_colorCode); slotType.setDataType(DT_VOICE_PI_HEADER); slotType.getData(data + 2U); // Convert the Data Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_DATA); data[0U] = TAG_DATA; data[1U] = 0x00U; writeQueue(data); #if defined(DUMP_DMR) writeFile(data); #endif } else if (dataType == DT_TERMINATOR_WITH_LC) { if (m_state != RS_RELAYING_NETWORK_AUDIO) return; // Regenerate the Slot Type CSlotType slotType; slotType.setColorCode(m_colorCode); slotType.setDataType(DT_TERMINATOR_WITH_LC); slotType.getData(data + 2U); // Convert the Data Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_DATA); data[0U] = TAG_EOT; data[1U] = 0x00U; writeQueue(data); writeEndOfTransmission(); #if defined(DUMP_DMR) writeFile(data); closeFile(); #endif // We've received the voice header and terminator haven't we? m_frames += 2U; LogMessage("DMR Slot %u, received network end of voice transmission, %u%% packet loss, BER: %u%%", m_slotNo, (m_lost * 100U) / m_frames, (m_errs * 100U) / m_bits); } else if (dataType == DT_DATA_HEADER) { if (m_state == RS_RELAYING_NETWORK_DATA) return; // Regenerate the Slot Type CSlotType slotType; slotType.setColorCode(m_colorCode); slotType.setDataType(DT_DATA_HEADER); slotType.getData(data + 2U); // Convert the Data Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_DATA); data[0U] = TAG_DATA; data[1U] = 0x00U; // Put a small delay into starting transmission writeQueue(m_idle); writeQueue(m_idle); for (unsigned i = 0U; i < 3U; i++) writeQueue(data); m_state = RS_RELAYING_NETWORK_DATA; // setShortLC(m_slotNo, m_lc->getDstId(), m_lc->getFLCO()); // m_display->writeDMR(m_slotNo, m_lc->getSrcId(), m_lc->getFLCO() == FLCO_GROUP, m_lc->getDstId()); // LogMessage("DMR Slot %u, received network data header from %u to %s%u", m_slotNo, m_lc->getSrcId(), m_lc->getFLCO() == FLCO_GROUP ? "TG " : "", m_lc->getDstId()); LogMessage("DMR Slot %u, received network data header", m_slotNo); } else if (dataType == DT_VOICE_SYNC) { if (m_state != RS_RELAYING_NETWORK_AUDIO) return; // Initialise the lost packet data if (m_frames == 0U) { m_seqNo = dmrData.getSeqNo(); m_n = dmrData.getN(); m_elapsed.start(); m_lost = 0U; } else { insertSilence(dmrData.getSeqNo()); } // Convert the Audio Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_AUDIO); unsigned char fid = m_lc->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) m_errs += m_fec.regenerateDMR(data + 2U); m_bits += 216U; data[0U] = TAG_DATA; data[1U] = 0x00U; writeQueue(data); m_packetTimer.start(); m_frames++; // Save details in case we need to infill data m_seqNo = dmrData.getSeqNo(); m_n = dmrData.getN(); ::memcpy(m_lastFrame, data, DMR_FRAME_LENGTH_BYTES + 2U); #if defined(DUMP_DMR) writeFile(data); #endif } else if (dataType == DT_VOICE) { if (m_state != RS_RELAYING_NETWORK_AUDIO) return; // Initialise the lost packet data if (m_frames == 0U) { m_seqNo = dmrData.getSeqNo(); m_n = dmrData.getN(); m_elapsed.start(); m_lost = 0U; } else { insertSilence(dmrData.getSeqNo()); } unsigned char fid = m_lc->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) m_errs += m_fec.regenerateDMR(data + 2U); m_bits += 216U; // Change the color code in the EMB CEMB emb; emb.putData(data + 2U); emb.setColorCode(m_colorCode); emb.getData(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; writeQueue(data); m_packetTimer.start(); m_frames++; // Save details in case we need to infill data m_seqNo = dmrData.getSeqNo(); m_n = dmrData.getN(); ::memcpy(m_lastFrame, data, DMR_FRAME_LENGTH_BYTES + 2U); #if defined(DUMP_DMR) writeFile(data); #endif } else { // Change the Color Code of the Slot Type CSlotType slotType; slotType.putData(data + 2U); slotType.setColorCode(m_colorCode); slotType.getData(data + 2U); // Convert the Data Sync to be from the BS CDMRSync sync; sync.addSync(data + 2U, DST_BS_DATA); data[0U] = TAG_DATA; data[1U] = 0x00U; writeQueue(data); #if defined(DUMP_DMR) writeFile(data); #endif } }