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
Dispatcher.cpp
00001 /** 00002 * @file Dispatcher.cpp 00003 * @brief BLE UART RPC dispatcher implmentation 00004 * @author Doug Anson 00005 * @version 1.0 00006 * @see 00007 * 00008 * Copyright (c) 2014 00009 * 00010 * Licensed under the Apache License, Version 2.0 (the "License"); 00011 * you may not use this file except in compliance with the License. 00012 * You may obtain a copy of the License at 00013 * 00014 * http://www.apache.org/licenses/LICENSE-2.0 00015 * 00016 * Unless required by applicable law or agreed to in writing, software 00017 * distributed under the License is distributed on an "AS IS" BASIS, 00018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00019 * See the License for the specific language governing permissions and 00020 * limitations under the License. 00021 */ 00022 00023 #include "Dispatcher.h" 00024 #include "UartRPCFunctions.h" 00025 00026 // forward declarations 00027 extern "C" int ble_rpc_recv_data(uint8_t *buffer,int buffer_length); 00028 00029 #ifdef DBG 00030 #undef DBG 00031 #endif 00032 #define DBG std::printf 00033 00034 // constructor 00035 Dispatcher::Dispatcher(BLEDevice &ble) : m_uart(ble), m_splitter(), m_splitter_count(0), m_splitter_index(0) { 00036 ble.onDataWritten(this,&Dispatcher::onDataWritten); 00037 memset(this->m_send_packet,0,MAX_PACKET_LENGTH+1); 00038 } 00039 00040 void Dispatcher::onDataWritten(const GattCharacteristicWriteCBParams *params) { 00041 int length = (int)params->len; 00042 uint8_t *data = (uint8_t *)params->data; 00043 bool send_ack = false; 00044 //DBG("onDataWritten: received: [%s] length=%d\r\n",data,length); 00045 00046 if (strstr((char *)data,"ACK") == NULL) { 00047 // process this input from the peer 00048 ble_rpc_recv_data(data,length); 00049 00050 // we received something... so send an ack 00051 send_ack = true; 00052 } 00053 else { 00054 // received an ACK so note it... 00055 //DBG("onDataWritten: received ACK (OK)... continuing...\r\n"); 00056 ; 00057 } 00058 00059 // write the next segment (if any...) 00060 this->uart_write(send_ack); 00061 } 00062 00063 int Dispatcher::uart_write(bool send_ack) { 00064 if (this->m_splitter_count > 0) { 00065 int length = this->m_splitter.getSplitLength(); // fixed 00066 int index = this->m_splitter_index; 00067 if (index < (this->m_splitter_count-1)) { 00068 // wont be partial length... 00069 //DBG("dispatcher(): sending segment %d (of %d): [%s]\r\n",index+1,this->m_splitter.getNumFragments(),this->m_splitter.get(index)); 00070 this->uart_write(this->m_splitter.get(index),UART_SEGMENT_LENGTH); 00071 } 00072 else { 00073 // partial length so we pad with spaces... 00074 uint8_t *tmp = this->m_splitter.get(index); 00075 int padded_length = strlen((char *)tmp); 00076 int diff = UART_SEGMENT_LENGTH-padded_length; 00077 for(int j=0;j<diff;++j) memcpy((tmp+padded_length+j)," ",1); 00078 padded_length = strlen((char *)tmp); 00079 00080 // send the last segment which may be a partial length one... 00081 //DBG("dispatcher(): sending segment %d (of %d): [%s] length: %d (padded %d)...\r\n",index+1,this->m_splitter.getNumFragments(),tmp,padded_length,diff); 00082 this->uart_write(tmp,padded_length); 00083 } 00084 00085 // update splitter index 00086 ++this->m_splitter_index; 00087 00088 // note when we are done... 00089 if (this->m_splitter_index == this->m_splitter_count) { 00090 this->m_splitter_index = 0; 00091 this->m_splitter_count = 0; 00092 this->m_splitter.reset(); 00093 } 00094 00095 // return the length 00096 //DBG("dispatcher(): sent %d bytes\r\n",length); 00097 return length; 00098 } 00099 else if (send_ack) { 00100 // just send and ack as we received something... 00101 //DBG("dispatcher(): sending ACK...\r\n"); 00102 return this->uart_write((uint8_t *)"ACK\n",4); 00103 } 00104 else { 00105 // nothing to send 00106 //DBG("dispatcher(): nothing to send()...\r\n"); 00107 return 0; 00108 } 00109 } 00110 00111 int Dispatcher::uart_write(uint8_t *data,int data_length) { 00112 return this->m_uart.write(data,data_length); 00113 } 00114 00115 // dispatch 00116 int Dispatcher::dispatch(uint8_t fn_id,uint8_t *args,int args_length,uint8_t *response,int response_length) { 00117 //DBG("dispatcher(): fn_id=0x%.2x args=[%s] args_length=%d response_length=%d\r\n",fn_id,args,args_length,response_length); 00118 //DBG("dispatcher(): fn_id=0x%.2x args_length=%d response_length=%d\r\n",fn_id,args_length,response_length); 00119 00120 // prepare the send packet 00121 //DBG("dispatcher(): preparing the send packet...\r\n"); 00122 int len = this->prepare_send_packet(fn_id,args,args_length); 00123 00124 // Split into chunks and pad the last one 00125 //DBG("dispatcher(): splitting into segments for UART transmission...\r\n"); 00126 this->m_splitter.reset(); 00127 this->m_splitter_count = this->m_splitter.split(this->m_send_packet,len); 00128 00129 // send the first of the segments and wait for an ack... 00130 this->m_splitter_index = 0; 00131 len = this->uart_write(); 00132 00133 // return the number of bytes sent... 00134 //DBG("dispatcher(): send started. sent %d bytes...\r\n",len); 00135 return len; 00136 } 00137 00138 // prepare the packet to send 00139 int Dispatcher::prepare_send_packet(uint8_t fn_id,uint8_t *args,int args_length) { 00140 // clear the packet 00141 memset(this->m_send_packet,0,MAX_PACKET_LENGTH+1); 00142 sprintf((char *)this->m_send_packet,"[%d|%s]",fn_id,args); 00143 return strlen((char *)this->m_send_packet); 00144 }
Generated on Sun Jul 17 2022 05:11:06 by 1.7.2