Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: libnsdl_m0 BLE_API Base64 nRF51822 SplitterAssembler
Revision 5:9233e88b9c83, committed 2015-02-16
- Comitter:
- ansond
- Date:
- Mon Feb 16 06:37:35 2015 +0000
- Parent:
- 4:a3a1bc1718ba
- Child:
- 6:98af441fd960
- Commit message:
- updates - pre-RPC
Changed in this revision
--- a/NSDL/nsdl_support.cpp Sat Feb 14 08:45:12 2015 +0000
+++ b/NSDL/nsdl_support.cpp Mon Feb 16 06:37:35 2015 +0000
@@ -137,9 +137,6 @@
register_endpoint(false);
DBG("NSP: (re)registering complete.\r\n");
}
- else {
- DBG("NSP: BLE not connected. Skipping re-registration...\r\n");
- }
}
void nsdl_init() {
@@ -194,12 +191,13 @@
ble.waitForEvent();
// only process if we are registered and thus connected... otherwise ignore
- if (__registered) {
+ if (__registered == true) {
//DBG("NSP: waiting for data...\r\n");
int n = server.receiveFrom(from,nsp_buffer,sizeof(nsp_buffer));
-
- //DBG("NSP: received %d bytes... processing..\r\n.",n);
- if (n >= 0) sn_nsdl_process_coap((uint8_t*)nsp_buffer,n,&received_packet_address);
+ if (n >= 0) {
+ DBG("NSP: received %d bytes... processing..\r\n.",n);
+ sn_nsdl_process_coap((uint8_t*)nsp_buffer,n,&received_packet_address);
+ }
}
}
}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bt_network/BleUartRPC/Buffer.lib Mon Feb 16 06:37:35 2015 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/sam_grove/code/Buffer/#7b754354b99c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bt_network/BleUartRPC/Dispatcher.cpp Mon Feb 16 06:37:35 2015 +0000
@@ -0,0 +1,31 @@
+/**
+ * @file Dispatcher.cpp
+ * @brief BLE UART RPC dispatcher implmentation
+ * @author Doug Anson
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ #include "Dispatcher.h"
+
+ // constructor
+ Dispatcher::Dispatcher(BLEDevice &ble,int rxsize,int txsize) : m_uart(ble), m_rxbuf(rxsize), m_txbuf(txsize) {
+ }
+
+ // dispatch
+ bool Dispatcher::dispatch(uint8_t fn_id,uint8_t *args,int args_length,uint8_t *response,int response_length) {
+ }
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bt_network/BleUartRPC/Dispatcher.h Mon Feb 16 06:37:35 2015 +0000
@@ -0,0 +1,58 @@
+/**
+ * @file Dispatcher.h
+ * @brief BLE UART RPC dispatcher header
+ * @author Doug Anson
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ #ifndef __RPC_DISPATCH_H__
+ #define __RPC_DISPATCH_H__
+
+ #include "BLEDevice.h"
+ #include "UARTService.h"
+
+ #include "Buffer.h"
+
+ class Dispatcher {
+ public:
+ /**
+ Default constructor
+ @param ble the BLEDevice instance
+ @param rxsize the size of the receive ring buffer (default is 1024)
+ @param txsize the size of the transmit ring buffer (default is 1024)
+ */
+ Dispatcher(BLEDevice &ble,int rxsize = 1024,int txsize = 1024);
+
+ /**
+ Dispatch function request with arguments (already serialized and prepared for transport)
+ @param fn_id the identifier for the target remote function to invoke
+ @param args the serialized function argument array list
+ @param args_length the length of the serialized function argument list
+ @param response the received response buffer
+ @param response_length the recieved response buffer length
+ @returns true - dispatch succeeded, false - otherwise
+ */
+ bool dispatch(uint8_t fn_id,uint8_t *args,int args_length,uint8_t *response,int response_length);
+
+ private:
+ UARTService m_uart;
+ Buffer<char> m_rxbuf;
+ Buffer<char> m_txbuf;
+ };
+
+ #endif // __RPC_DISPATCH_H__
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bt_network/BleUartRPC/UartRPC.cpp Mon Feb 16 06:37:35 2015 +0000
@@ -0,0 +1,49 @@
+/**
+ * @file UartRPC.cpp
+ * @brief BLE UART RPC implementation
+ * @author Doug Anson
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ #include "UartRPC.h"
+
+ #include "Base64.h"
+
+ #ifdef DBG
+ #undef DBG
+ #endif
+ #define DBG std::printf
+
+ // constructor
+ UartRPC::UartRPC(BLEDevice &ble) : m_dispatcher(ble) {
+ }
+
+ // dispatch RPC
+ bool UartRPC::dispatch(uint8_t fn_id,uint8_t *response,int response_length,const char *format,...)
+ {
+ // serialize the variable arguments into a long string...
+ va_list args;
+ uint8_t buffer[MAX_ARGUMENT_LENGTH+1];
+ memset(buffer,0,sizeof(buffer));
+ va_start(args, format);
+ vsnprintf((char *)buffer,MAX_ARGUMENT_LENGTH,format,args);
+ va_end(args);
+
+ // dispatch now...
+ return this->m_dispatcher.dispatch(fn_id,buffer,strlen((char *)buffer),response,response_length);
+ }
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bt_network/BleUartRPC/UartRPC.h Mon Feb 16 06:37:35 2015 +0000
@@ -0,0 +1,43 @@
+/**
+ * @file UartRPC.h
+ * @brief BLE UART RPC header
+ * @author Doug Anson
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ #ifndef __UART_RPC_H__
+ #define __UART_RPC_H__
+
+ #include "mbed.h"
+ #include <stdarg.h>
+ #include "BLEDevice.h"
+ #include "Dispatcher.h"
+
+ #define MAX_ARGUMENT_LENGTH 1024 // longest argument sent as parameter list
+ #define MAX_RESULT_LENGTH 1024 // longest result received
+
+ class UartRPC {
+ public:
+ UartRPC(BLEDevice &ble);
+ bool dispatch(uint8_t fn_id,uint8_t *response,int response_length,const char *format,...);
+
+ private:
+ Dispatcher m_dispatcher;
+ };
+
+ #endif // __UART_RPC_H__
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bt_network/BleUartRPC/UartRPCFunctions.cpp Mon Feb 16 06:37:35 2015 +0000
@@ -0,0 +1,126 @@
+/**
+ * @file UartRPCFunctions.cpp
+ * @brief BLE UART RPC stubs implementation
+ * @author Doug Anson
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ #include "UartRPCFunctions.h"
+ #include "UartRPC.h"
+
+
+ #include "Base64.h"
+
+ #ifdef DBG
+ #undef DBG
+ #endif
+ #define DBG std::printf
+
+ typedef enum {
+ SOCKET_OPEN_FN = 0x01,
+ SOCKET_CLOSE_FN = 0x02,
+ SEND_DATA_FN = 0x04,
+ RECV_DATA_FN = 0x08,
+ NUM_FNs = 4
+ } FunctionIDs;
+
+ UartRPC *__rpc = NULL;
+
+ void ble_rpc_init(BLEDevice &ble)
+ {
+ if (__rpc == NULL) __rpc = new UartRPC(ble);
+ }
+
+ bool ble_rpc_open_udp_socket(char *ip_address,int port)
+ {
+ bool success = false;
+ uint8_t response[2];
+ memset(response,0,sizeof(response));
+ if (__rpc->dispatch(SOCKET_OPEN_FN,response,sizeof((char *)response),"%s %d",ip_address,port)) {
+ // success
+ int reply = 0;
+ scanf((char *)response,"%d",&reply);
+ if (reply == 1) success = true;
+ }
+ else {
+ // failure
+ DBG("ble_rpc_open_udp_socket: dispatch() failed\r\n");
+ }
+ return success;
+ }
+
+ bool ble_rpc_close_udp_socket(void)
+ {
+ bool success = false;
+ uint8_t response[2];
+ memset(response,0,sizeof(response));
+ if (__rpc->dispatch(SOCKET_CLOSE_FN,response,sizeof((char *)response),"%s","")) {
+ // success
+ int reply = 0;
+ scanf((char *)response,"%d",&reply);
+ if (reply == 1) success = true;
+ }
+ else {
+ // failure
+ DBG("ble_rpc_close_udp_socket: dispatch() failed\r\n");
+ }
+ return success;
+ }
+
+ bool ble_rpc_send_data(uint8_t *data,int data_length)
+ {
+ bool success = false;
+ uint8_t response[2];
+ memset(response,0,sizeof(response));
+ Base64 b64;
+ int base64_data_length = MAX_ARGUMENT_LENGTH;
+ char *base64_data = b64.Encode((char *)data,data_length,(std::size_t *)&base64_data_length);
+ if (__rpc->dispatch(SEND_DATA_FN,response,sizeof((char *)response),"%s",base64_data)) {
+ // success
+ int reply = 0;
+ scanf((char *)response,"%d",&reply);
+ if (reply == 1) success = true;
+ }
+ else {
+ // failure
+ DBG("ble_rpc_send_data: dispatch() failed\r\n");
+ }
+ if (base64_data != NULL) free(base64_data);
+ return success;
+ }
+
+ int ble_rpc_recv_data(uint8_t *buffer,int buffer_length)
+ {
+ uint8_t base64_buffer[MAX_RESULT_LENGTH+1];
+ memset(base64_buffer,0,sizeof(base64_buffer));
+ if (__rpc->dispatch(RECV_DATA_FN,base64_buffer,MAX_RESULT_LENGTH,"%s","")) {
+ // success
+ Base64 b64;
+ int base64_length = buffer_length;
+ char *raw_buffer = b64.Decode((char *)base64_buffer,strlen((char *)base64_buffer),(std::size_t *)&base64_length);
+ memcpy(buffer,raw_buffer,base64_length);
+ if (raw_buffer != NULL) free(raw_buffer);
+ return base64_length;
+ }
+ else {
+ // failure
+ DBG("ble_rpc_recv_data: dispatch() failed\r\n");
+ }
+ return -1;
+ }
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bt_network/BleUartRPC/UartRPCFunctions.h Mon Feb 16 06:37:35 2015 +0000 @@ -0,0 +1,34 @@ +/** + * @file UartRPCFunctions.h + * @brief BLE UART RPC stubs header + * @author Doug Anson + * @version 1.0 + * @see + * + * Copyright (c) 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef __UART_RPC_FUNCTIONS_H__ + #define __UART_RPC_FUNCTIONS_H__ + + #include "UartRPC.h" + + extern "C" void ble_rpc_init(BLEDevice &ble); + extern "C" bool ble_rpc_open_udp_socket(char *ip_address,int port); + extern "C" bool ble_rpc_close_udp_socket(void); + extern "C" bool ble_rpc_send_data(uint8_t *data,int data_length); + extern "C" int ble_rpc_recv_data(uint8_t *buffer,int buffer_length); + + #endif // __UART_RPC_FUNCTIONS_H__ \ No newline at end of file
--- a/bt_network/SplitterAssembler.lib Sat Feb 14 08:45:12 2015 +0000 +++ b/bt_network/SplitterAssembler.lib Mon Feb 16 06:37:35 2015 +0000 @@ -1,1 +1,1 @@ -http://developer.mbed.org/users/ansond/code/SplitterAssembler/#5614523d641b +http://developer.mbed.org/users/ansond/code/SplitterAssembler/#00f7a99862a3
--- a/network_stubs/network_stubs.cpp Sat Feb 14 08:45:12 2015 +0000
+++ b/network_stubs/network_stubs.cpp Mon Feb 16 06:37:35 2015 +0000
@@ -24,6 +24,7 @@
#include "BLEDevice.h"
#include "UARTService.h"
+
#include "Base64.h"
#include "SplitterAssembler.h"
@@ -37,8 +38,10 @@
BLEDevice ble;
UARTService *uart = NULL;
volatile bool __registered = false;
+SplitterAssembler splitter;
+Base64 b64;
-static const uint16_t uuid16_list[] = {GattService::UUID_DEVICE_INFORMATION_SERVICE};
+static const uint16_t deviceInfoServiceUUID[] = {GattService::UUID_DEVICE_INFORMATION_SERVICE};
char _ipAddress[IP_ADDRESS_LENGTH];
int _ipPort;
@@ -64,7 +67,7 @@
{
memset(_connectionRecord,0,MAX_CONNECTION_RECORD_LENGTH+1);
sprintf(_connectionRecord,"1|%s|%d",_ipAddress,_ipPort);
- DBG("ble_build_connection_record: Connection Record: %s",_connectionRecord);
+ DBG("ble_build_connection_record: Connect Record: %s\r\n",_connectionRecord);
}
// build disconnection record
@@ -72,7 +75,7 @@
{
memset(_connectionRecord,0,MAX_CONNECTION_RECORD_LENGTH+1);
printf(_connectionRecord,"0|%s|%d",_ipAddress,_ipPort);
- DBG("ble_build_disconnection_record: Connection Record: %s",_connectionRecord);
+ DBG("ble_build_disconnection_record: Disconnect Record: %s\r\n",_connectionRecord);
}
// BLE Disconnection callback
@@ -87,15 +90,16 @@
// BLE Connection callback
void ble_connect_callback(Gap::Handle_t handle, Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, const Gap::ConnectionParams_t *params)
{
+ wait_ms(3000); // wait for 3 seconds... let the gateway register the device completely and get ready to accept data...
+
if (__registered == false) {
DBG("ble_connect_callback: BLE connected! Creating connection record...\r\n");
ble_build_connection_record();
DBG("ble_connect_callback: Sending connection record...\r\n");
ble_send_data((uint8_t *)_connectionRecord,strlen(_connectionRecord),false);
- // wait a bit... let the gateway connect...
- wait_ms(2000);
-
+ wait_ms(3000); // wait for 3 seconds... let the gateway register the device completely and get ready to accept data...
+
// NSP registration
DBG("ble_connect_callback: calling NSP registration...\r\n");
register_endpoint(true);
@@ -109,6 +113,8 @@
// send the disconnection record
void ble_send_disconnection_record()
{
+ DBG("Building disconnection record...\r\n");
+ ble_build_disconnection_record();
DBG("Sending disconnection record...\r\n");
ble_send_data((uint8_t *)_connectionRecord,strlen(_connectionRecord),false);
}
@@ -117,6 +123,7 @@
void ble_init(void)
{
// BLE initialization and callback setup
+ __registered = false;
ble.init();
ble.onDisconnection(ble_disconnect_callback);
ble.onConnection(ble_connect_callback);
@@ -129,11 +136,13 @@
DBG("Starting BLE Advertising (%s)...\r\n",endpoint_name);
ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
- ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
+ ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_REMOTE_CONTROL);
ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME,(uint8_t *)endpoint_name,strlen((char *)endpoint_name));
- ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
- ble.setAdvertisingInterval(1600); /* 1000ms; in multiples of 0.625ms. */
+ ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,(const uint8_t *)endpoint_name, strlen((char *)endpoint_name));
+ ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,(uint8_t *)deviceInfoServiceUUID, sizeof(deviceInfoServiceUUID));
+ ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID, sizeof(UARTServiceUUID));
+ ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000));
ble.startAdvertising();
}
@@ -150,29 +159,30 @@
if (sendHeader) {
char header[10];
- uint8_t buffer[1024];
+ uint8_t buffer[256];
- memset(header,0,10);
- memset(buffer,0,1024);
+ memset(header,0,sizeof(header));
+ memset(buffer,0,sizeof(buffer));
- Base64 encoder;
- int b64_data_len = 1024; // initial sizing for malloc() in Base64...
- char *b64_data = encoder.Encode((char *)data,data_len,(std::size_t *)&b64_data_len);
+ // Base64 Encode + Add Length Header...
+ int b64_data_len = sizeof(buffer); // initial sizing for malloc() in Base64...
+ char *b64_data = b64.Encode((char *)data,data_len,(std::size_t *)&b64_data_len);
sprintf(header,"%d|",b64_data_len);
int header_length = strlen(header);
memcpy(buffer,header,header_length);
memcpy((buffer+header_length),b64_data,b64_data_len);
+
+ // write if we have a UART...
if (uart != NULL) {
- DBG("Output: [%s] length=%d...",buffer,(header_length+b64_data_len));
-
- // SPLIT
- SplitterAssembler splitter;
+ // Split into fragments...
int num_fragments = splitter.split(buffer,header_length+b64_data_len);
sent = 0;
for(int i=0;i<num_fragments;++i) {
- sent += uart->write((const void *)splitter.get(i),strlen((char *)splitter.get(i)));
+ int i_sent = uart->write((const void *)splitter.get(i),strlen((char *)splitter.get(i)));
+ int diff = splitter.getSplitLength() - i_sent;
+ sent += i_sent;
+ for(int j=0;j<diff;++j) uart->write((const void *)"\0",1);
}
- uart->write("\n",strlen("\n"));
}
if (b64_data != NULL) free(b64_data);
}
@@ -180,7 +190,8 @@
// plumbing headers are simple and dont need the data length header...
if (uart != NULL) {
sent = uart->write((const void *)data,data_len);
- uart->write("\n",strlen("\n"));
+ int diff = splitter.getSplitLength() - sent;
+ for(int j=0;j<diff;++j) uart->write((const void *)"\0",1);
}
}
@@ -191,18 +202,65 @@
// BLE recv data
int ble_recv_data(uint8_t *buffer,int buffer_len)
{
+ // initialize...
int received = 0;
- memset(buffer,0,buffer_len);
- if (uart != NULL) received = uart->read(buffer,buffer_len);
- DBG("in ble_recv_data() buffer_len=%d buffer: [",buffer_len);
- for(int i=0;i<received;++i) {
- DBG("%.2x",buffer[i]);
- if (i < (received-1)) DBG(" ");
+ uint8_t encoded_buffer[1024];
+ memset(encoded_buffer,0,sizeof(encoded_buffer));
+
+ // receive
+ if (uart != NULL) received = uart->read(encoded_buffer,buffer_len);
+
+ // look for the length header first
+ for(int i=0;i<received;++i) {
+ if (encoded_buffer[i] == '|') encoded_buffer[i] = ' ';
}
- DBG("] received %d bytes\r\n",received);
-
- // return the recieved number of bytes
- return received;
+ uint8_t tmp_buffer[1024];
+ memset((char *)tmp_buffer,0,sizeof(tmp_buffer));
+ int num_bytes = 0;
+ sscanf((char *)encoded_buffer,"%d %s",&num_bytes,tmp_buffer);
+ if (num_bytes > 0) {
+ DBG("in ble_recv_data(): need to read a total of %d bytes...\r\n",num_bytes);
+
+ // read more...
+ num_bytes -= strlen((char *)tmp_buffer);
+ int index = strlen((char *)tmp_buffer);
+ DBG("in ble_recv_data(): Initial buffer: [%s] index=%d, num_bytes=%d\r\n",tmp_buffer,index,num_bytes);
+ for(int i=0;i<num_bytes;++i) {
+ DBG("in ble_recv_data() reading byte %d...\r\n",i);
+ tmp_buffer[index] = uart->_getc();
+ ++index;
+ }
+
+ buffer_len = strlen((char *)tmp_buffer);
+ memset(encoded_buffer,0,sizeof(encoded_buffer));
+ memcpy(encoded_buffer,tmp_buffer,buffer_len);
+ received = buffer_len;
+
+ // DEBUG
+ DBG("in ble_recv_data() buffer_len=%d ",buffer_len);
+ DBG("encoded_buffer: [%s](%d) ",encoded_buffer,strlen((char *)encoded_buffer));
+ DBG("received %d bytes\r\n",received);
+
+ // decode and copy to the input buffer
+ int raw_data_len = buffer_len; // initial sizing for malloc() in Base64...
+ char *raw_data = b64.Decode((char *)encoded_buffer,received,(std::size_t *)&raw_data_len);
+
+ // copy...
+ memset(buffer,0,buffer_len);
+ int length = raw_data_len;
+ if (length > buffer_len) length = buffer_len;
+ memcpy(buffer,raw_data,length);
+
+ // clean up
+ if (raw_data != NULL) free(raw_data);
+
+ // return the recieved number of bytes
+ return received;
+ }
+ else {
+ DBG("in ble_recv_data() no bytes to read...\r\n");
+ return 0;
+ }
}
// plumb out the network