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

Committer:
ansond
Date:
Tue Nov 03 17:03:51 2015 +0000
Revision:
38:30e71f1206b1
Parent:
36:aa73681951ad
merged with IoS and android tweaks

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 5:9233e88b9c83 1 /**
ansond 5:9233e88b9c83 2 * @file Dispatcher.cpp
ansond 5:9233e88b9c83 3 * @brief BLE UART RPC dispatcher implmentation
ansond 5:9233e88b9c83 4 * @author Doug Anson
ansond 5:9233e88b9c83 5 * @version 1.0
ansond 5:9233e88b9c83 6 * @see
ansond 5:9233e88b9c83 7 *
ansond 5:9233e88b9c83 8 * Copyright (c) 2014
ansond 5:9233e88b9c83 9 *
ansond 5:9233e88b9c83 10 * Licensed under the Apache License, Version 2.0 (the "License");
ansond 5:9233e88b9c83 11 * you may not use this file except in compliance with the License.
ansond 5:9233e88b9c83 12 * You may obtain a copy of the License at
ansond 5:9233e88b9c83 13 *
ansond 5:9233e88b9c83 14 * http://www.apache.org/licenses/LICENSE-2.0
ansond 5:9233e88b9c83 15 *
ansond 5:9233e88b9c83 16 * Unless required by applicable law or agreed to in writing, software
ansond 5:9233e88b9c83 17 * distributed under the License is distributed on an "AS IS" BASIS,
ansond 5:9233e88b9c83 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ansond 5:9233e88b9c83 19 * See the License for the specific language governing permissions and
ansond 5:9233e88b9c83 20 * limitations under the License.
ansond 5:9233e88b9c83 21 */
ansond 5:9233e88b9c83 22
ansond 5:9233e88b9c83 23 #include "Dispatcher.h"
ansond 33:4f6929e123f2 24 #include "UartRPCFunctions.h"
ansond 5:9233e88b9c83 25
ansond 33:4f6929e123f2 26 // forward declarations
ansond 9:bf0cf5828378 27 extern "C" int ble_rpc_recv_data(uint8_t *buffer,int buffer_length);
ansond 33:4f6929e123f2 28
ansond 6:98af441fd960 29 #ifdef DBG
ansond 6:98af441fd960 30 #undef DBG
ansond 6:98af441fd960 31 #endif
ansond 6:98af441fd960 32 #define DBG std::printf
ansond 6:98af441fd960 33
ansond 5:9233e88b9c83 34 // constructor
ansond 9:bf0cf5828378 35 Dispatcher::Dispatcher(BLEDevice &ble) : m_uart(ble), m_splitter(), m_splitter_count(0), m_splitter_index(0) {
ansond 9:bf0cf5828378 36 ble.onDataWritten(this,&Dispatcher::onDataWritten);
ansond 9:bf0cf5828378 37 memset(this->m_send_packet,0,MAX_PACKET_LENGTH+1);
ansond 9:bf0cf5828378 38 }
ansond 9:bf0cf5828378 39
ansond 9:bf0cf5828378 40 void Dispatcher::onDataWritten(const GattCharacteristicWriteCBParams *params) {
ansond 9:bf0cf5828378 41 int length = (int)params->len;
ansond 9:bf0cf5828378 42 uint8_t *data = (uint8_t *)params->data;
ansond 9:bf0cf5828378 43 bool send_ack = false;
ansond 14:bcb9a9ffd425 44 //DBG("onDataWritten: received: [%s] length=%d\r\n",data,length);
ansond 9:bf0cf5828378 45
ansond 9:bf0cf5828378 46 if (strstr((char *)data,"ACK") == NULL) {
ansond 9:bf0cf5828378 47 // process this input from the peer
ansond 9:bf0cf5828378 48 ble_rpc_recv_data(data,length);
ansond 9:bf0cf5828378 49
ansond 9:bf0cf5828378 50 // we received something... so send an ack
ansond 9:bf0cf5828378 51 send_ack = true;
ansond 9:bf0cf5828378 52 }
ansond 9:bf0cf5828378 53 else {
ansond 9:bf0cf5828378 54 // received an ACK so note it...
ansond 16:fb9c3f2af2df 55 //DBG("onDataWritten: received ACK (OK)... continuing...\r\n");
ansond 16:fb9c3f2af2df 56 ;
ansond 9:bf0cf5828378 57 }
ansond 9:bf0cf5828378 58
ansond 9:bf0cf5828378 59 // write the next segment (if any...)
ansond 9:bf0cf5828378 60 this->uart_write(send_ack);
ansond 9:bf0cf5828378 61 }
ansond 9:bf0cf5828378 62
ansond 9:bf0cf5828378 63 int Dispatcher::uart_write(bool send_ack) {
ansond 9:bf0cf5828378 64 if (this->m_splitter_count > 0) {
ansond 9:bf0cf5828378 65 int length = this->m_splitter.getSplitLength(); // fixed
ansond 9:bf0cf5828378 66 int index = this->m_splitter_index;
ansond 9:bf0cf5828378 67 if (index < (this->m_splitter_count-1)) {
ansond 9:bf0cf5828378 68 // wont be partial length...
ansond 16:fb9c3f2af2df 69 //DBG("dispatcher(): sending segment %d (of %d): [%s]\r\n",index+1,this->m_splitter.getNumFragments(),this->m_splitter.get(index));
ansond 9:bf0cf5828378 70 this->uart_write(this->m_splitter.get(index),UART_SEGMENT_LENGTH);
ansond 9:bf0cf5828378 71 }
ansond 9:bf0cf5828378 72 else {
ansond 9:bf0cf5828378 73 // partial length so we pad with spaces...
ansond 9:bf0cf5828378 74 uint8_t *tmp = this->m_splitter.get(index);
ansond 9:bf0cf5828378 75 int padded_length = strlen((char *)tmp);
ansond 9:bf0cf5828378 76 int diff = UART_SEGMENT_LENGTH-padded_length;
ansond 9:bf0cf5828378 77 for(int j=0;j<diff;++j) memcpy((tmp+padded_length+j)," ",1);
ansond 9:bf0cf5828378 78 padded_length = strlen((char *)tmp);
ansond 9:bf0cf5828378 79
ansond 9:bf0cf5828378 80 // send the last segment which may be a partial length one...
ansond 16:fb9c3f2af2df 81 //DBG("dispatcher(): sending segment %d (of %d): [%s] length: %d (padded %d)...\r\n",index+1,this->m_splitter.getNumFragments(),tmp,padded_length,diff);
ansond 9:bf0cf5828378 82 this->uart_write(tmp,padded_length);
ansond 9:bf0cf5828378 83 }
ansond 9:bf0cf5828378 84
ansond 9:bf0cf5828378 85 // update splitter index
ansond 9:bf0cf5828378 86 ++this->m_splitter_index;
ansond 9:bf0cf5828378 87
ansond 9:bf0cf5828378 88 // note when we are done...
ansond 9:bf0cf5828378 89 if (this->m_splitter_index == this->m_splitter_count) {
ansond 9:bf0cf5828378 90 this->m_splitter_index = 0;
ansond 9:bf0cf5828378 91 this->m_splitter_count = 0;
ansond 9:bf0cf5828378 92 this->m_splitter.reset();
ansond 9:bf0cf5828378 93 }
ansond 9:bf0cf5828378 94
ansond 9:bf0cf5828378 95 // return the length
ansond 35:71eb3663ecbd 96 //DBG("dispatcher(): sent %d bytes\r\n",length);
ansond 9:bf0cf5828378 97 return length;
ansond 9:bf0cf5828378 98 }
ansond 9:bf0cf5828378 99 else if (send_ack) {
ansond 35:71eb3663ecbd 100 // just send and ack as we received something...
ansond 35:71eb3663ecbd 101 //DBG("dispatcher(): sending ACK...\r\n");
ansond 9:bf0cf5828378 102 return this->uart_write((uint8_t *)"ACK\n",4);
ansond 9:bf0cf5828378 103 }
ansond 9:bf0cf5828378 104 else {
ansond 9:bf0cf5828378 105 // nothing to send
ansond 35:71eb3663ecbd 106 //DBG("dispatcher(): nothing to send()...\r\n");
ansond 9:bf0cf5828378 107 return 0;
ansond 9:bf0cf5828378 108 }
ansond 6:98af441fd960 109 }
ansond 6:98af441fd960 110
ansond 6:98af441fd960 111 int Dispatcher::uart_write(uint8_t *data,int data_length) {
ansond 11:d601b867b297 112 return this->m_uart.write(data,data_length);
ansond 5:9233e88b9c83 113 }
ansond 5:9233e88b9c83 114
ansond 5:9233e88b9c83 115 // dispatch
ansond 6:98af441fd960 116 int Dispatcher::dispatch(uint8_t fn_id,uint8_t *args,int args_length,uint8_t *response,int response_length) {
ansond 11:d601b867b297 117 //DBG("dispatcher(): fn_id=0x%.2x args=[%s] args_length=%d response_length=%d\r\n",fn_id,args,args_length,response_length);
ansond 16:fb9c3f2af2df 118 //DBG("dispatcher(): fn_id=0x%.2x args_length=%d response_length=%d\r\n",fn_id,args_length,response_length);
ansond 11:d601b867b297 119
ansond 6:98af441fd960 120 // prepare the send packet
ansond 16:fb9c3f2af2df 121 //DBG("dispatcher(): preparing the send packet...\r\n");
ansond 6:98af441fd960 122 int len = this->prepare_send_packet(fn_id,args,args_length);
ansond 6:98af441fd960 123
ansond 6:98af441fd960 124 // Split into chunks and pad the last one
ansond 16:fb9c3f2af2df 125 //DBG("dispatcher(): splitting into segments for UART transmission...\r\n");
ansond 9:bf0cf5828378 126 this->m_splitter.reset();
ansond 9:bf0cf5828378 127 this->m_splitter_count = this->m_splitter.split(this->m_send_packet,len);
ansond 6:98af441fd960 128
ansond 9:bf0cf5828378 129 // send the first of the segments and wait for an ack...
ansond 9:bf0cf5828378 130 this->m_splitter_index = 0;
ansond 11:d601b867b297 131 len = this->uart_write();
ansond 6:98af441fd960 132
ansond 6:98af441fd960 133 // return the number of bytes sent...
ansond 16:fb9c3f2af2df 134 //DBG("dispatcher(): send started. sent %d bytes...\r\n",len);
ansond 6:98af441fd960 135 return len;
ansond 6:98af441fd960 136 }
ansond 6:98af441fd960 137
ansond 6:98af441fd960 138 // prepare the packet to send
ansond 6:98af441fd960 139 int Dispatcher::prepare_send_packet(uint8_t fn_id,uint8_t *args,int args_length) {
ansond 6:98af441fd960 140 // clear the packet
ansond 6:98af441fd960 141 memset(this->m_send_packet,0,MAX_PACKET_LENGTH+1);
ansond 6:98af441fd960 142 sprintf((char *)this->m_send_packet,"[%d|%s]",fn_id,args);
ansond 6:98af441fd960 143 return strlen((char *)this->m_send_packet);
ansond 5:9233e88b9c83 144 }