BLE mbed Endpoint network stack for mbedConnectorInterface. The stack makes use of a special BLE Socket abstraction to create socket() semantics over BLE.
Dependencies: libnsdl_m0 BLE_API Base64 nRF51822 SplitterAssembler
bt_network/BleUartRPC/Dispatcher.cpp
- Committer:
- ansond
- Date:
- 2015-11-03
- Revision:
- 38:30e71f1206b1
- Parent:
- 36:aa73681951ad
File content as of revision 38:30e71f1206b1:
/** * @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" #include "UartRPCFunctions.h" // forward declarations extern "C" int ble_rpc_recv_data(uint8_t *buffer,int buffer_length); #ifdef DBG #undef DBG #endif #define DBG std::printf // constructor Dispatcher::Dispatcher(BLEDevice &ble) : m_uart(ble), m_splitter(), m_splitter_count(0), m_splitter_index(0) { ble.onDataWritten(this,&Dispatcher::onDataWritten); memset(this->m_send_packet,0,MAX_PACKET_LENGTH+1); } void Dispatcher::onDataWritten(const GattCharacteristicWriteCBParams *params) { int length = (int)params->len; uint8_t *data = (uint8_t *)params->data; bool send_ack = false; //DBG("onDataWritten: received: [%s] length=%d\r\n",data,length); if (strstr((char *)data,"ACK") == NULL) { // process this input from the peer ble_rpc_recv_data(data,length); // we received something... so send an ack send_ack = true; } else { // received an ACK so note it... //DBG("onDataWritten: received ACK (OK)... continuing...\r\n"); ; } // write the next segment (if any...) this->uart_write(send_ack); } int Dispatcher::uart_write(bool send_ack) { if (this->m_splitter_count > 0) { int length = this->m_splitter.getSplitLength(); // fixed int index = this->m_splitter_index; if (index < (this->m_splitter_count-1)) { // wont be partial length... //DBG("dispatcher(): sending segment %d (of %d): [%s]\r\n",index+1,this->m_splitter.getNumFragments(),this->m_splitter.get(index)); this->uart_write(this->m_splitter.get(index),UART_SEGMENT_LENGTH); } else { // partial length so we pad with spaces... uint8_t *tmp = this->m_splitter.get(index); int padded_length = strlen((char *)tmp); int diff = UART_SEGMENT_LENGTH-padded_length; for(int j=0;j<diff;++j) memcpy((tmp+padded_length+j)," ",1); padded_length = strlen((char *)tmp); // send the last segment which may be a partial length one... //DBG("dispatcher(): sending segment %d (of %d): [%s] length: %d (padded %d)...\r\n",index+1,this->m_splitter.getNumFragments(),tmp,padded_length,diff); this->uart_write(tmp,padded_length); } // update splitter index ++this->m_splitter_index; // note when we are done... if (this->m_splitter_index == this->m_splitter_count) { this->m_splitter_index = 0; this->m_splitter_count = 0; this->m_splitter.reset(); } // return the length //DBG("dispatcher(): sent %d bytes\r\n",length); return length; } else if (send_ack) { // just send and ack as we received something... //DBG("dispatcher(): sending ACK...\r\n"); return this->uart_write((uint8_t *)"ACK\n",4); } else { // nothing to send //DBG("dispatcher(): nothing to send()...\r\n"); return 0; } } int Dispatcher::uart_write(uint8_t *data,int data_length) { return this->m_uart.write(data,data_length); } // dispatch int Dispatcher::dispatch(uint8_t fn_id,uint8_t *args,int args_length,uint8_t *response,int response_length) { //DBG("dispatcher(): fn_id=0x%.2x args=[%s] args_length=%d response_length=%d\r\n",fn_id,args,args_length,response_length); //DBG("dispatcher(): fn_id=0x%.2x args_length=%d response_length=%d\r\n",fn_id,args_length,response_length); // prepare the send packet //DBG("dispatcher(): preparing the send packet...\r\n"); int len = this->prepare_send_packet(fn_id,args,args_length); // Split into chunks and pad the last one //DBG("dispatcher(): splitting into segments for UART transmission...\r\n"); this->m_splitter.reset(); this->m_splitter_count = this->m_splitter.split(this->m_send_packet,len); // send the first of the segments and wait for an ack... this->m_splitter_index = 0; len = this->uart_write(); // return the number of bytes sent... //DBG("dispatcher(): send started. sent %d bytes...\r\n",len); return len; } // prepare the packet to send int Dispatcher::prepare_send_packet(uint8_t fn_id,uint8_t *args,int args_length) { // clear the packet memset(this->m_send_packet,0,MAX_PACKET_LENGTH+1); sprintf((char *)this->m_send_packet,"[%d|%s]",fn_id,args); return strlen((char *)this->m_send_packet); }