/* * Demux.cpp * * Created on: 09/10/2008 * Author: lacet */ #include "filter.h" #include "packet.h" #include "section_hal.h" #include #include #include "demux.h" #include "demuxListener.h" #include "jmutex.h" #include "util.h" #define OK (0) //debug #define DEBUG 0 #define DEBUG_ARQ 0 FILE *file = NULL; Packet* myPacket = NULL; Mutex* mutex = new Mutex(); Demux::Demux(int pid) { //mutex->Lock(); //filters = new vector (); filter = new Filter(pid, 0, 0); //printf("\nFiltro Setado\n"); mySectionBuffer = new SectionBuffer(); mySectionBuffer->initSectionsBuffer(); sectionSize = -1; sectionRead = 0; countPacotes = 0; continuityCounter = 0; lastContinuityCounter = 0; flagShiftPointerField = 1; //setDemuxListener(); //mutex->Unlock(); } Demux::Demux(int pid, DemuxListener* listener) { //mutex->Lock(); //filters = new vector (); filter = new Filter(pid, 0, 0); //printf("\nFiltro Setado\n"); mySectionBuffer = new SectionBuffer(); mySectionBuffer->initSectionsBuffer(); sectionSize = -1; sectionRead = 0; countPacotes = 0; continuityCounter = 0; lastContinuityCounter = 0; setDemuxListener(listener); //mutex->Unlock(); ouvintes = new list(); // Inicia o mutex mutex = (pthread_mutex_t *) malloc(sizeof (pthread_mutex_t)); pthread_mutex_init(mutex, NULL); } void Demux::setDemuxListener(DemuxListener* listener) { this->listener = listener; } void Demux::chegouInput(unsigned char *pacote) { // Mutex para evitar bug multiplas chamadas dos notificadores pthread_mutex_lock(mutex); Packet *mypack = new Packet(pacote); getNextSection(pacote, mypack); pthread_mutex_unlock(mutex); } Demux::~Demux() { delete filter; delete mySectionBuffer; if (ouvintes) { // nao deleta os ouvintes mesmo, apenas a lista ouvintes->clear(); delete ouvintes; } if (mutex) { int ret = pthread_mutex_destroy(mutex); if (ret) printf("erro destruindo mutex\n"); free(mutex); } } Filter* Demux::getFilter() { return filter; } int getPESSize(unsigned char* pacote) { return getIntAtBits(pacote, 32, 16) + 6; } int start = 0; //int countPacotes = 0; int Demux::getNextSection(unsigned char* packet, Packet *myPacket) { //countPacotes++; //unsigned char* packet = new unsigned char[PACKET_SIZE]; // TODO desalocar unsigned char *payloadData; static utils::Util util; int packetControl = OK; //Filter* filter; //int packetControl; int count1, count2; count1 = count2 = 0; //printf("\nPacket Notified - PID: %d\nSection Read: %d\n", myPacket->getPid(), sectionRead); //this->flagShiftPointerField = 1; if (myPacket && filter) { if (packetControl == OK) { if (myPacket->getPid() != filter->getFilterPid()) { //printf("\nRefused Packet - PID: %d\n", myPacket->getPid()); //invalid pid return 0; } else if (myPacket->getPayloadLength() < 1) { //printf("\nEmpty Payload\n"); return 0; //empty payload } else { //cout << "Accepted Packet - PID: " << myPacket->getPid() << endl; continuityCounter = myPacket->getContinuityCounter(); //printf("\nContinuity Counter: %d\n", continuityCounter); if (start == 0) { start = 1; } else { if (lastContinuityCounter == 15) { if (continuityCounter != 0) { //cout << "ERRO DE CONTINUIDADE!!" << endl; //cout << "PID: " << myPacket->getPid() << endl; //cout << "CC: " << continuityCounter << endl; //cout << "LCC: " << lastContinuityCounter << endl; lastContinuityCounter = continuityCounter; sectionRead = 0; sectionSize = -1; return OK; } } else if (continuityCounter != (lastContinuityCounter + 1)) { //cout << "ERRO DE CONTINUIDADE!" << endl; //cout << "PID: " << myPacket->getPid() << endl; //cout << "CC: " << continuityCounter << endl; //cout << "LCC: " << lastContinuityCounter << endl; lastContinuityCounter = continuityCounter; sectionRead = 0; sectionSize = -1; return OK; } } } lastContinuityCounter = continuityCounter; } } else { //printf("\nInvalid Packet\n"); return 0; //invalid packet } payloadData = myPacket->getPayloadCopy(); payloadSize = myPacket->getPayloadLength(); // TODO validate continuity_counter if (myPacket->hasAdaptationField()) { int tamanho = packet[4]; payloadData = (unsigned char *) myPacket->getPayloadBeginingAtUnitStarted(); payloadSize = myPacket->getPayloadBeginingAtUnitStartedLength(); if (payloadData[0] == 0x00 && payloadData[1] == 0x00 && payloadData[2] == 0x01) { //cout << "Pegou Payload Correto" << endl; } else { cout << "Pegou Payload Errado" << endl; } } else { } if (sectionRead == 0) { sectionSize = getPESSize(payloadData); if (sectionSize > payloadSize) { memcpy(sectionData, payloadData, payloadSize); sectionRead += payloadSize; } else { memcpy(sectionData, payloadData, sectionSize); sectionRead += sectionSize; } if (sectionData[0] == 0x00 && sectionData[1] == 0x00 && sectionData[2] == 0x01) { //cout << "Pacote PES OK!" << endl; } else { sectionRead = 0; sectionSize = -1; cout << "Pacote PES ERRADO!" << endl; } } else { if ((sectionSize - sectionRead) > payloadSize) { memcpy(sectionData + sectionRead, payloadData, payloadSize); sectionRead += payloadSize; } else { memcpy(sectionData + sectionRead, payloadData, (sectionSize - sectionRead)); sectionRead += (sectionSize - sectionRead); } } if (sectionRead == sectionSize) { sectionSize = getPESSize(sectionData); //cout << "PES NOTIFIED - PES Size: " << sectionSize << endl; listener->notifySection(myPacket->getPid(), sectionData, sectionSize); sectionRead = 0; sectionSize = -1; } delete myPacket; return OK; } void Demux::registraOuvinte(OuvinteDemux * ouvinte) { ouvintes->push_back(ouvinte); } void Demux::removeOuvinte(OuvinteDemux * ouvinte) { ouvintes->remove(ouvinte); } void Demux::notificaOuvintes(unsigned char * sec) { for (list::iterator i = ouvintes->begin(); i != ouvintes->end(); i++) { (*i)->chegou(sec); } }