XBee_Address::XBee_Address(const GBeeRxPacket *rx) : node("") { addr16 = GBEE_USHORT(rx->srcAddr16); addr64h = GBEE_ULONG(rx->srcAddr64h); addr64l = GBEE_ULONG(rx->srcAddr64l); }
GBeeError gbeeSendTxRequest(GBee *self, uint8_t frameId, uint32_t dstAddr64h, uint32_t dstAddr64l, uint16_t dstAddr16, uint8_t bcastRadius, uint8_t options, uint8_t *data, uint16_t length) { // Error code returned by GBee. GBeeError error = GBEE_NO_ERROR; // 16bit address Tx request parameters. GBeeTxRequest txRequest; // Check some pre-conditions. if (self->lastError != GBEE_NO_ERROR) { error = GBEE_INHERITED_ERROR; } GBEE_THROW(error); // Assemble the AT command frame. txRequest.ident = GBEE_TX_REQUEST; txRequest.frameId = frameId; txRequest.dstAddr64h = GBEE_ULONG(dstAddr64h); txRequest.dstAddr64l = GBEE_ULONG(dstAddr64l); txRequest.dstAddr16 = GBEE_USHORT(dstAddr16); txRequest.bcastRadius = bcastRadius; txRequest.options = options; GBEE_PORT_MEMORY_COPY(txRequest.data, data, length); // Send the AT command frame. error = gbeeSend(self, (GBeeFrameData *)&txRequest, length + GBEE_TX_REQUEST_HEADER_LENGTH); return error; }
GBeeError gbeeSendRemoteAtCommand(GBee *self, uint8_t frameId, uint32_t dstAddr64h, uint32_t dstAddr64l, uint16_t dstAddr16, uint8_t *atCmd, uint8_t cmdOpts, uint8_t *value, uint16_t length) { // Error code returned by GBee. GBeeError error = GBEE_NO_ERROR; // Remote AT command parameters. GBeeRemoteAtCommand remoteAtCommand; // Check some pre-conditions. if (self->lastError != GBEE_NO_ERROR) { error = GBEE_INHERITED_ERROR; } GBEE_THROW(error); // Assemble the AT command frame. remoteAtCommand.ident = GBEE_REMOTE_AT_COMMAND; remoteAtCommand.frameId = frameId; remoteAtCommand.dstAddr64h = GBEE_ULONG(dstAddr64h); remoteAtCommand.dstAddr64l = GBEE_ULONG(dstAddr64l); remoteAtCommand.dstAddr16 = GBEE_USHORT(dstAddr16); remoteAtCommand.atCommand[0] = atCmd[0]; remoteAtCommand.atCommand[1] = atCmd[1]; remoteAtCommand.cmdOpts = cmdOpts; GBEE_PORT_MEMORY_COPY(remoteAtCommand.value, value, length); // Send the AT command frame. error = gbeeSend(self, (GBeeFrameData *)&remoteAtCommand, length + GBEE_REMOTE_AT_COMMAND_HEADER_LENGTH); return error; }
GBeeError gbeeSend(GBee *self, GBeeFrameData *frameData, uint16_t length) { // Pointer to header of frame to send. GBeeFrameHeader *frameHeader = (GBeeFrameHeader *)&self->scratch[0]; // Pointer to trailer of frame to send. GBeeFrameTrailer *frameTrailer = (GBeeFrameTrailer *)&self->scratch[sizeof(GBeeFrameHeader)+length]; // GBee error code. GBeeError error = GBEE_NO_ERROR; // Total frame size. uint16_t totalLength; // Check some pre-conditions. if (self->lastError != GBEE_NO_ERROR) { error = GBEE_INHERITED_ERROR; } else if (length > GBEE_MAX_FRAME_SIZE) { error = GBEE_FRAME_SIZE_ERROR; } GBEE_THROW(error); // Create frame to send to the XBee. frameHeader->startDelimiter = 0x7E; frameHeader->length = GBEE_USHORT(length); GBEE_PORT_MEMORY_COPY(&self->scratch[sizeof(GBeeFrameHeader)], frameData, length); frameTrailer->checksum = gbeeCalculateChecksum((uint8_t *)frameData, length); totalLength = length + sizeof(GBeeFrameHeader) + sizeof(GBeeFrameTrailer); // Print the GBee message to send if debug logging is enabled. #ifdef GBEE_PORT_DEBUG_LOG { uint16_t byteNr; printf("%s: ", __func__); for (byteNr = 0; byteNr < totalLength; byteNr++) { printf("%02x ", byteNr); } printf("\r\n"); } #endif // GBEE_PORT_DEBUG_LOG // Send the frame via the serial interface. error = GBEE_PORT_UART_SEND_BUFFER(self->serialDevice, self->scratch, totalLength); return error; }
GBeeError gbeeReceive(GBee *self, GBeeFrameData *frameData, uint16_t *length, uint32_t *timeout) { // Header of frame. GBeeFrameHeader frameHeader; // Trailer of frame. GBeeFrameTrailer frameTrailer; // Pointer to current byte being processed. uint8_t *bytePtr; // Size of received frame. uint8_t frameSize; // Elapsed time for reception. uint8_t elapsedTime; // GBee error code. GBeeError error = GBEE_NO_ERROR; // GBee read error code. GBeeError readError; // Check some pre-conditions. if (self->lastError != GBEE_NO_ERROR) { error = GBEE_INHERITED_ERROR; } GBEE_THROW(error); // Prepare. *length = 0; frameSize = 0; frameHeader.startDelimiter = 0; frameHeader.length = 0; elapsedTime = 0; bytePtr = (uint8_t*)&frameHeader; GBEE_DEBUG_LOG("%s: ", __func__); // Loop to read the frame byte-wise. while (error == GBEE_NO_ERROR) { if ((*timeout != GBEE_NO_WAIT) && (*timeout != GBEE_INFINITE_WAIT)) { // Check if timeout expired. if (elapsedTime >= (*timeout)) { error = GBEE_TIMEOUT_ERROR; break; } (*timeout) -= elapsedTime; } // Get timestamp. elapsedTime = GBEE_PORT_TIME_GET(); // Read a byte from the serial interface. readError = GBEE_PORT_UART_RECEIVE_BYTE(self->serialDevice, bytePtr, *timeout); // Calculate elapsed time. elapsedTime = GBEE_PORT_TIME_GET() - elapsedTime; GBEE_DEBUG_LOG("%02x ", *bytePtr); // Check for errors. if (readError != GBEE_NO_ERROR) { error = GBEE_FRAME_INTEGRITY_ERROR; break; } // First byte must be the start delimiter. if ((frameSize > 0) || (frameHeader.startDelimiter == 0x7E)) { // Got a byte, so increment the frame size. frameSize++; // Got the header? Read the data. if (frameSize == sizeof(GBeeFrameHeader)) { if (GBEE_USHORT(frameHeader.length) > GBEE_MAX_FRAME_SIZE) { error = GBEE_FRAME_SIZE_ERROR; break; } bytePtr = (uint8_t *)frameData; } // Got the data? Read the trailer. else if (frameSize == (sizeof(GBeeFrameHeader) + GBEE_USHORT(frameHeader.length))) { bytePtr = (uint8_t *)&frameTrailer; } // Got the trailer? Verify checksum. else if (frameSize == (sizeof(GBeeFrameHeader) + sizeof(GBeeFrameTrailer) + GBEE_USHORT(frameHeader.length))) { // Verify checksum. if (gbeeVerifyChecksum((uint8_t *)frameData, GBEE_USHORT(frameHeader.length), frameTrailer.checksum) != GBEE_NO_ERROR) { error = GBEE_CHECKSUM_ERROR; break; } else { *length = GBEE_USHORT(frameHeader.length); error = GBEE_NO_ERROR; break; } } // Keep reading. else { bytePtr++; } } } GBEE_DEBUG_LOG("\r\n"); return error; }