libJelling-calc/SRC/bluetooth.cpp

286 lines
7.9 KiB
C++

#include "bluetooth.h"
#define RETURN Timer_Start(this->timer);return;
/* --------------------------------------------------- */
/* --------------------------------------------------- */
/* ----------------- CLASS BLUETOOTH ----------------- */
/* --------------------------------------------------- */
/* --------------------------------------------------- */
Bluetooth::Bluetooth(){
this->sentPacketsTotalSize = 0;
this->receivedPacketsTotalSize = 0;
this->unread = 0;
this->allowReception = 1;
this->ID = 0;
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(1000);
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::setSender(char *senderName){
if(strlen(senderName)+1 <= 10){
if(strlen(senderName) >= 0){
memcpy(this->sender, senderName, strlen(senderName)+1);
}else{
return SENDER_EMPTY;
}
}else{
return SENDER_TOO_BIG;
}
return 0;
}
int Bluetooth::sendMessage(Message *message){
int split, RTCTime, temp;
char *ptr2;
unsigned char dateEx[] = "YYYY-MM-DD-HH-MM-SS";
split = (int)((message->getLength())/208) + (message->getLength()%208) == 0 ? 0:1;
if((ptr2 = (char*)malloc(256)) == NULL) return NOT_ENOUGH_RAM;
this->ID++;
PrintMini(1,1,(const unsigned char*)itoa(split),MINI_OR);
for(int i=0; i<split; i++){
memcpy(ptr2,dateEx, 19);
if(message->getType() == NULL){
memcpy(ptr2+19,"RQT",3);
}else{
memcpy(ptr2+19, message->getType(), 3);
}
if(message->isHeader){
memcpy(ptr+22, message->msg+22, sizeof(int));
memcpy(ptr+26, message->msg+26, 10);
}else{
memcpy(ptr+22, (int*)this->ID, sizeof(int));
memcpy(ptr+26, this->sender, 10);
}
memcpy(ptr2+36, (int*)message->getLength(), sizeof(int));
memcpy(ptr2+40, (int*)(((i+1)*208 > message->getLength()) ? (message->getLength() - i*208) : 208), sizeof(int));
memcpy(ptr2+44, (unsigned short*)(i+1), sizeof(unsigned short));
memcpy(ptr2+46, (unsigned short*)split, sizeof(unsigned short));
memcpy(ptr2+48, (int*)(message->getMessage()+i*208, ((i+1)*208 > message->getLength()) ? (message->getLength() - i*208) : 208), sizeof(int));
Serial_WriteBytes((unsigned char*)ptr2,50);
RTCTime = RTC_GetTicks();
while(Serial_GetTxBufferFreeCapacity() != 0){
if((RTC_GetTicks() - RTCTime)/RTC > 300){
free(ptr2);
this->ID--;
return UNKNOWN_ERROR;
}
}
}
free(ptr2);
return 0;
}
Message& Bluetooth::getLastMessage(){
return msg;
}
void Bluetooth::receptMessage(){
int size, errorID;
int RTCTime;
int messageLength = 48;
int typeCase;
char buffer[50];
int lengthPackets[2];
unsigned short partsNumber[2] = {(unsigned short)0,(unsigned short)1};
const char type[7][4] = {"RQT","ASW","ACK","MIS","FUL","ERR","END"};
const char err[1][4] = {"ERR"};
char ptr2[3];
unsigned int messageID;
Message sendBack;
if((this->secondTry = Serial_GetRxBufferSize()) == 1000 || this->secondTry==Serial_GetRxBufferSize()){
// if allowReception. else, send back a FUL packet to the device
if(this->allowReception){
Serial_ReadBytes((unsigned char*)this->ptr1ko, 1000,(short*)&size);
memcpy(ptr2, this->ptr1ko+19, 3);
typeCase = tabcmp((const char**)type, 7, ptr2);
switch(typeCase){
case RQT:
case END:
case ASW:
memcpy(&this->ID, (unsigned int*)this->ptr1ko+22, sizeof(unsigned int));
if(size < 48){
sendBack.init("HED", this->ID, this->sender, "");
sendMessage(&sendBack);
RETURN
}
memcpy(this->sender, this->ptr1ko+26, 10);
for(unsigned short i=0; i<partsNumber[1]; i++){
memcpy(&messageID, (unsigned int*)this->ptr1ko+22, sizeof(unsigned int));
if(messageID != this->ID){
sendBack.init("ERR", messageID, this->sender, "INCORRECT ID");
sendMessage(&sendBack);
RETURN }
memcpy(lengthPackets, this->ptr1ko+36, sizeof(lengthPackets));
sprintf(buffer,"%d", i+1);
if(partsNumber[0] != i+1){
if(partsNumber[0] > i+1){
sendBack.init("MIS", messageID, this->sender, buffer);
sendMessage(&sendBack);
}else{
sendBack.init("ACK", messageID, this->sender, buffer);
sendMessage(&sendBack);
}
}else if(lengthPackets[1] != size-48){
sendBack.init("ERR", messageID, this->sender, "INCOMPLETE PACKET SIZE");
sendMessage(&sendBack);
RETURN
}else{
messageLength+=size-48;
memcpy(this->ptr+48+i*952, this->ptr1ko+48, 952);
sendBack.init("ACK", messageID, this->sender, buffer);
sendMessage(&sendBack);
if(messageLength-48 == lengthPackets[0] && partsNumber[0] == partsNumber[1]){
if(!(errorID = msg.setTotalMessage(this->ptr))){
this->unread = 1;
this->allowReception = 0;
this->ID++;
RETURN
}else{
sendBack.init("ERR", messageID, this->sender, (char*)&err[errorID]);
sendMessage(&sendBack);
RETURN
}
}
}
RTCTime = RTC_GetTicks();
while(Serial_GetRxBufferSize() != (lengthPackets[0]-messageLength-48>1000 ? 1000 : lengthPackets[0]-messageLength-48)){
if((RTC_GetTicks() - RTCTime)/RTC > 300){
RETURN
}
}
memcpy(partsNumber, this->ptr1ko+44, sizeof(partsNumber));
}
break;
}
}else{
sendBack.init("FUL", this->ID, this->sender, "");
sendMessage(&sendBack);
RETURN
}
}else if(Serial_GetRxBufferSize()>0){
this->secondTry = Serial_GetRxBufferSize();
RETURN
}
}
/* --------------------------------------------------- */
/* --------------------------------------------------- */
/* ------------------ CLASS MESSAGE ------------------ */
/* --------------------------------------------------- */
/* --------------------------------------------------- */
Message::Message(){
this->isHeader = 0;
this->isType = 0;
this->msg = (char*)NULL;
}
int Message::init(const char* type, int ID, char* sender,const char* message){
if(setType(type)) return INVALID_TYPE;
if(setMessage(message)) return NOT_ENOUGH_RAM;
return 0;
}
int Message::setType(const char *typeH){
memcpy(this->type, typeH, 3);
this->isType = 1;
return 0;
}
int Message::setMessage(const char *message){
int length;
length = strlen(message) + 49;
this->msg = (char*)realloc(this->msg, length);
if(this->msg == NULL) return NOT_ENOUGH_RAM;
memcpy(this->msg+48, message, length-48);
return 0;
}
int Message::setTotalMessage(char *message){
this->msg = message;
this->isHeader = 1;
return 0;
}
char* Message::getTime(){
if(this->isHeader){
return this->msg;
}else{
return (char*)NULL;
}
}
char* Message::getType(){
if(this->isHeader || this->isType){
return this->msg+19;
}else{
return (char*)NULL;
}
}
char* Message::getSender(){
if(this->isHeader){
return this->msg+26;
}else{
return (char*)NULL;
}
}
int Message::getLength(){
if(this->msg == NULL) return -1;
return strlen(this->msg+48)+1;
}
unsigned char* Message::getMessage(){
return (unsigned char*)this->msg+48;
}
int tabcmp(const char *tab[4], int size, char* string){
for(int i=0; i<size; i++){
if(!strncmp(tab[i], string, 4)) return i;
}
return -1;
}
char *itoa(int i){
static char buf[21];
char *p = buf + 20;
if (i >= 0) {
do{
*--p = '0' + (i % 10);
i /= 10;
}while (i != 0);
return p;
}else {
do {
*--p = '0' - (i % 10);
i /= 10;
}while (i != 0);
*--p = '-';
}
return p;
}