#include "libJelling/bluetooth.h" Bluetooth::Bluetooth(){ this->sentPacketsTotalSize = 0; this->receivedPacketsTotalSize = 0; this->unread = 0; this->allowReception = 1; srand(RTC_GetTicks()); this->caltoID = rand(); this->secondTry = 0; memcpy(this->sender, "HC-06\0", 6); } int Bluetooth::listen(int maxSize, int timer, void(*func)(void), int time){ unsigned char conf[6] = {0, 5, 0, 0, 0, 0}; max = maxSize; this->ptr = (char*)malloc(maxSize); this->ptr1ko = (char*)malloc(SIZE_DATA_RX); if(this->ptr == NULL || this->ptr1ko == NULL) return NOT_ENOUGH_RAM; this->timer = Timer_Install(timer, func, time); if(Serial_Open(conf) == 3) return SERIAL_ALREADY_OPEN; Timer_Start(this->timer); return 0; } int Bluetooth::stop(){ Serial_Close(1); return 0; } int Bluetooth::setSender(const char *senderName){ if(strlen(senderName)+1 <= 10){ if(strlen(senderName) > 0){ memcpy(this->sender, senderName, strlen(senderName)+1); }else{ return TOO_SHORT; } }else{ return TOO_LONG; } return 0; } int Bluetooth::sendMessage(Message *message){ int RTCTime, tempInt; unsigned short tempShort, split; char *ptr2; unsigned char dateEx[] = "YYYY-MM-DD-HH-MM-SS"; split = (unsigned short)(message->getLength()/SIZE_DATA_TX + (message->getLength()%SIZE_DATA_TX == 0 ? 0:1)); if((ptr2 = (char*)malloc(SIZE_TX)) == NULL) return NOT_ENOUGH_RAM; Timer_Stop(this->timer); for(unsigned short i=0; igetType() != NULL) ? message->getType() : RQT; if(message->getID() != -1){ tempInt = message->getID(); memcpy(ptr2+ID_POS, &tempInt, sizeof(int)); }else memcpy(ptr2+ID_POS, &this->caltoID, sizeof(int)); memcpy(ptr2+SENDER_POS, (message->getSender() != NULL) ? message->getSender() : this->sender, 10); tempInt = message->getLength(); memcpy(ptr2+MESSAGE_LENGTH_POS, &tempInt, sizeof(int)); tempInt = (i+1)*SIZE_DATA_TX > message->getLength() ? message->getLength()-i*SIZE_DATA_TX : SIZE_DATA_TX; memcpy(ptr2+PACKET_LENGTH_POS, &tempInt, sizeof(int)); tempShort = i+1; memcpy(ptr2+PART_POS, &tempShort, sizeof(unsigned short)); memcpy(ptr2+NUMBER_PART_POS, &split, sizeof(unsigned short)); memcpy(ptr2+SIZE_HEADER, (char*)message->getMessage()+i*SIZE_DATA_TX, tempInt); Serial_WriteBytes((unsigned char*)ptr2,SIZE_HEADER+tempInt); RTCTime = RTC_GetTicks(); while(Serial_GetTxBufferFreeCapacity() < SIZE_TX){ if((RTC_GetTicks() - RTCTime)/RTC > 300){ free(ptr2); Timer_Start(this->timer); return UNKNOWN_ERROR; } } } RTCTime = RTC_GetTicks(); isWaitingAck = true; while(this->lastID != this->caltoID){ if((RTC_GetTicks() - RTCTime)/RTC > 300){ free(ptr2); Timer_Start(this->timer); isWaitingAck = false; return MISSING_ACK; } } isWaitingAck = false; free(ptr2); this->caltoID++; Timer_Start(this->timer); return 0; } Message& Bluetooth::getLastMessage(){ return msg; } void Bluetooth::receptMessage(){ int size, errorID; int RTCTime; int messageLength = SIZE_HEADER; char buffer[50]; int lengthPackets[2]; unsigned short partsNumber[2] = {(unsigned short)0,(unsigned short)1}; const char err[1][4] = {"ERR"}; unsigned int messageID; Message sendBack; if((this->secondTry = Serial_GetRxBufferSize()) == SIZE_DATA_RX || ((int)this->secondTry==Serial_GetRxBufferSize() && this->secondTry != 0)){ Serial_ReadBytes((unsigned char*)this->ptr1ko, SIZE_DATA_RX,(short*)&size); this->secondTry = 0; switch((unsigned char)*(this->ptr1ko+TYPE_POS)){ case ACK: if(isWaitingAck){ this->lastType = ACK; memcpy(&this->lastID, (unsigned int*)this->ptr1ko+SIZE_HEADER, sizeof(unsigned int)); } RETURN case SYN: this->caltoID = rand(); sendBack.init(SYN+ACK, this->caltoID, this->sender, "test"); sendMessage(&sendBack); RETURN case RQT: case END: case ASW: // if allowReception. else, send back a FUL packet to the device if(this->allowReception){ if(size >= ID_POS + 4) memcpy(&messageID, (unsigned int*)this->ptr1ko+ID_POS, sizeof(unsigned int)); if(size < SIZE_HEADER){ if(size >= ID_POS + 4)sendBack.init(HED, this->caltoID, this->sender, (char*)messageID); else sendBack.init(HED, this->caltoID, this->sender, "\0"); sendMessage(&sendBack); RETURN } memcpy(this->sender, this->ptr1ko+ID_POS + 4, 10); for(unsigned short i=0; iptr1ko+ID_POS, sizeof(unsigned int)); if(messageID != this->androidID){ sprintf(buffer,"INCORRECT ID %d-%d",messageID,this->androidID); sendBack.init(ERR, messageID, this->sender, buffer); sendMessage(&sendBack); RETURN } memcpy(lengthPackets, this->ptr1ko+PACKET_LENGTH_POS, sizeof(lengthPackets)); sprintf(buffer,"%d", i+1); if(partsNumber[0] != i+1){ if(partsNumber[0] > i+1){ sendBack.init(ERR, messageID, this->sender, buffer); sendMessage(&sendBack); }else{ sendBack.init(ACK, messageID, this->sender, buffer); sendMessage(&sendBack); } }else if(lengthPackets[1] != size-SIZE_HEADER){ sprintf(buffer, "INCOMPLETE PACKET SIZE %d", this->androidID); sendBack.init(ERR, messageID, this->sender, buffer); sendMessage(&sendBack); RETURN }else{ messageLength+=size-SIZE_HEADER; memcpy(this->ptr+SIZE_HEADER+i*SIZE_DATA_RX, this->ptr1ko+SIZE_HEADER, SIZE_DATA_RX); sendBack.init(ACK, messageID, this->sender, buffer); sendMessage(&sendBack); if(messageLength-SIZE_HEADER == lengthPackets[0] && partsNumber[0] == partsNumber[1]){ if(!(errorID = msg.setTotalMessage(this->ptr))){ this->unread = 1; this->allowReception = 0; this->androidID++; RETURN }else{ sendBack.init(ERR, messageID, this->sender, (char*)&err[errorID]); sendMessage(&sendBack); RETURN } } } RTCTime = RTC_GetTicks(); while(Serial_GetRxBufferSize() != (lengthPackets[0]-messageLength-SIZE_HEADER>SIZE_DATA_RX ? SIZE_DATA_RX : lengthPackets[0]-messageLength-SIZE_HEADER)){ if((RTC_GetTicks() - RTCTime)/RTC > 300){ RETURN } } memcpy(partsNumber, this->ptr1ko+PART_POS, sizeof(partsNumber)); } }else{ sprintf(buffer, "%d",this->androidID); sendBack.init(FUL, this->caltoID, this->sender, buffer); sendMessage(&sendBack); RETURN } break; } }else if(Serial_GetRxBufferSize()>0){ this->secondTry = Serial_GetRxBufferSize(); RETURN } }