a

Dependents:   IOT_Sockets

Fork of xbee_api by Wiktor Grajkowski

xbeeFrame.cpp

Committer:
ammanvedi
Date:
2014-02-01
Revision:
11:c8737cf52430
Parent:
10:61e607fa8621

File content as of revision 11:c8737cf52430:

/* Copyright (c) 2014 Wiktor Grajkowski, Some Lincense
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
#include "xbee.h" 
#include "xbeeFrame.h"


xbeeFrame::xbeeFrame(PinName tx, PinName rx, PinName reset) : xbee(tx, rx, reset)
{
    _tx = tx;
    _rx = rx;
    _reset = reset;
}
xbeeFrame::~xbeeFrame()
{
}

void xbeeFrame::InitFrame(void)
{
    _frameType = TX_REQUEST_64;
    _frameID = 1;
    _options = 0;

}

void xbeeFrame::AssembleFrame(void)
{
    int cnt = 0;  //byte counter
    _apiFrame[cnt++] = STARTBYTE;  // starting delimiter
    int len = CalculateLength();  // calculate frame length
    _apiFrame[cnt++] = (len >> 8) & 0xff;  // put length msb
    _apiFrame[cnt++] = len & 0xff;         // put length lsb
    _apiFrame[cnt++] = _frameType; // put frame type
    _apiFrame[cnt++] = _frameID;   // put frame id
    char i;
    for(i=0; i<8; i++)
        _apiFrame[cnt++] = _destAddr[i];  // put destination address
    _apiFrame[cnt++] = _options;  // put other options
    char* p = _payload;
    while(*p)
        _apiFrame[cnt++] = *p++;  // put payload
    _apiFrame[cnt++] = CalculateChecksum();  //put checksum 
}

// calculates the checksum - http://www.digi.com/support/kbase/kbaseresultdetl?id=2206
char xbeeFrame::CalculateChecksum(void)
{
    int temp = 0;  // will sum up here
    int len = CalculateLength();
    char i;
    for(i=0; i<len; i++)
        temp+=_apiFrame[3+i];
    return 0xff - (temp & 0xff);
}

int xbeeFrame::CalculateLength(void)
{
    int cnt = 0;    // holds payload size
    char* p = _payload; 
    while(*p++)
        cnt++;
    cnt+=11; // frame type, frame id, 8 destination address bytes and options 
    _length[0] = (cnt >> 8) & 0xff;
    _length[1] = cnt & 0xff;
    return cnt;  
}

int xbeeFrame::GetLength(void)
{
    int len = (_length[0] << 8) + _length[1];
    return len;
}

int xbeeFrame::GetType(void)
{
    return _frameType;
}

int xbeeFrame::GetStatus(void)
{
    return _status;    
}

void xbeeFrame::SetDestination(unsigned char* dest)
{
    char i;
    for(i=0; i<8; i++)
        _destAddr[i] = *dest++;
}

void xbeeFrame::SetPayload(char* payload)
{
    _payload = payload;
}

void xbeeFrame::ParseFrame(void)
{
    char cnt = 3;
    _frameType = _apiFrame[cnt++];
    switch(_frameType)
    {
        case RX_PACKET_64:
        {
            char i;
            for(i=0; i<8; i++)
                _sourceAddr[i] = _apiFrame[cnt++];
            _rssi = _apiFrame[cnt++];
            _options = _apiFrame[cnt++];
            _payload = &(_apiFrame[cnt]);
            char* p = _rfData;
            for(i=0; i<GetLength()-11; i++)
                *p++ = _apiFrame[cnt++];
            *p = '\0';
            _checksum = _apiFrame[cnt++];
            break;
        }
        case TX_STATUS:
        {
            _frameID = _apiFrame[cnt++];
            _status = _apiFrame[cnt++];
            _checksum = _apiFrame[cnt];
            break;
        }
    }
}

void xbeeFrame::PrintData(void)
{
    printf("\rFrame received\n\r");
    printf("Length: %u\n\r", GetLength());
    printf("Frame Type: %X\n\r", _frameType);
    switch(_frameType)
    {
        case RX_PACKET_64:
        {
            printf("Source Address: ");
            char i;
            for(i=0; i<8; i++)
                printf("%X", _sourceAddr[i]);
            printf("\n\r");
            printf("RSSI: %u\n\r", _rssi);
            printf("Options: %X\n\r", _options);
            printf("RF Data: %s\n\r", _rfData);
            break;
        }
        case TX_STATUS:
        {
            printf("Frame ID: %X\n\r", _frameID);
            printf("Status: %X\n\r", _status);
            break;
        }
        default :
        printf("co jest kurwa?!\n\r");
    }
    printf("Checksum: %X\n\r", _checksum);
}

//todo add timeout
void xbeeFrame::ReceiveFrame(char* buf, int timeout)
{
    Timer t;
    t.start();
    _rfData = buf;
    int cnt = 0;  //byte counter
    char c;
    unsigned int len = 0;  //frame length + Startbyte
    char receivingFrame = 0;
    frameReceived = 0;
    Serial DATA(_tx,_rx);
    
    while(!frameReceived && (t.read_ms() < timeout))
    {
        if(DATA.readable())
        {
            c = DATA.getc();
            if(c == STARTBYTE)
                receivingFrame = 1;
            if(receivingFrame)
            {
                _apiFrame[cnt++] = c;
                if(cnt == 3)
                {
                  _length[0] = _apiFrame[1];
                  _length[1] = _apiFrame[2];
                  len = GetLength();
                }
                if(cnt>3 && (cnt == len + 4))  //startbyte, 2 len bytes and checksum
                {
                  receivingFrame = 0;
                  frameReceived = 1;
                  ParseFrame();
                }                
            }
        }
    }
}

char* xbeeFrame::GetFramePointer()
{
    return &_apiFrame[0];
}

void xbeeFrame::PrintPayload()
{
    char* p = _payload;
    while(*p != '\0')
        printf("%c", *p++);
}

void xbeeFrame::SendFrame(void)
{
    Serial DATA(_tx, _rx);
    int i;
    for (i=0; i<GetLength()+4; i++)
        DATA.printf("%c", _apiFrame[i]);
}