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
network_stubs.cpp
00001 /** 00002 * @file network_stubs.cpp 00003 * @brief mbed Endpoint network stubs implementation (BLE) 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 "network_stubs.h" 00024 00025 #include "UartRPCFunctions.h" 00026 00027 extern "C" { 00028 00029 // Globals 00030 BLEDevice ble; 00031 volatile bool __registered = false; 00032 00033 static const uint16_t deviceInfoServiceUUID[] = {GattService::UUID_DEVICE_INFORMATION_SERVICE}; 00034 00035 char _ipAddress[IP_ADDRESS_LENGTH]; 00036 int _ipPort; 00037 00038 // record the remote UDPSocket endpoint IP address 00039 void ble_set_remote_ip_address(const char *ipAddress,const int ipAddressLength) 00040 { 00041 memset(_ipAddress,0,IP_ADDRESS_LENGTH); 00042 int length = ipAddressLength; 00043 if (length > IP_ADDRESS_LENGTH) length = IP_ADDRESS_LENGTH; 00044 if (ipAddress != NULL) memcpy(_ipAddress,ipAddress,length); 00045 } 00046 00047 // record the remote UDPSocket endpoint port 00048 void ble_set_remote_ip_port(const int ipPort) 00049 { 00050 _ipPort = ipPort; 00051 } 00052 00053 // BLE Disconnection callback 00054 void ble_disconnect_callback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) 00055 { 00056 DBG("Disconnected handle %u!\r\n", handle); 00057 __registered = false; 00058 DBG("Restarting the advertising process\r\n"); 00059 ble.startAdvertising(); 00060 } 00061 00062 // BLE UDP socket open completion callback 00063 void ble_rpc_completed_open_udp_socket(bool opened) { 00064 if (opened) { 00065 // NSP registration 00066 DBG("ble_connect_callback: calling NSP registration...\r\n"); 00067 register_endpoint(true); 00068 DBG("ble_connect_callback: NSP registration completed\r\n"); 00069 00070 // registration completed 00071 __registered = true; 00072 } 00073 else { 00074 DBG("ble_connect_callback: remote UDP socket open FAILED...\r\n"); 00075 __registered = false; 00076 } 00077 } 00078 00079 #if defined(TARGET_STM32F411RE) || defined(TARGET_STM32F401RE) 00080 void ble_connect_callback(Gap::Handle_t handle, const Gap::ConnectionParams_t *reason) 00081 #else 00082 // BLE Connection callback 00083 void ble_connect_callback(Gap::Handle_t handle, Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, Gap::addr_type_t ownAddrType, const Gap::address_t ownAddr, const Gap::ConnectionParams_t *params) 00084 #endif 00085 { 00086 DBG("ble_connect_callback: BLE connected!...\r\n"); 00087 00088 // 9/4/15: Android 5.x appears to have some sort of poor-mans DDoS detector in its BLE stack so we have to slow things down a bit.. 00089 #ifdef ANDROID_BLE_DELAY 00090 wait_ms(ANDROID_BLE_DELAY_MS); 00091 #endif 00092 00093 if (__registered == false) { 00094 DBG("ble_connect_callback: Opening remote UDP socket to: %s@%d...\r\n",_ipAddress,_ipPort); 00095 ble_rpc_open_udp_socket(_ipAddress,_ipPort,&ble_rpc_completed_open_udp_socket); 00096 } 00097 else { 00098 DBG("ble_connect_callback: Already registered and connected...\r\n"); 00099 } 00100 } 00101 00102 // BLE Timeout callback 00103 void ble_timeout_callback(void) 00104 { 00105 DBG("BLE TIMEOUT OCCURED\r\n"); 00106 } 00107 00108 // BLE Init 00109 void ble_init(void) 00110 { 00111 // BLE initialization and callback setup 00112 __registered = false; 00113 ble.init(); 00114 ble.onDisconnection(ble_disconnect_callback); 00115 ble.onConnection(ble_connect_callback); 00116 ble.onTimeout(ble_timeout_callback); 00117 } 00118 00119 // BLE Begin Advertising 00120 void ble_begin_advertising(void) 00121 { 00122 extern uint8_t endpoint_name[NODE_NAME_LENGTH]; // our NSP NODE name 00123 00124 DBG("Starting BLE Advertising (%s)...\r\n",endpoint_name); 00125 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00126 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00127 ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_REMOTE_CONTROL); 00128 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME,(uint8_t *)endpoint_name,strlen((char *)endpoint_name)); 00129 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,(const uint8_t *)endpoint_name, strlen((char *)endpoint_name)); 00130 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,(uint8_t *)deviceInfoServiceUUID, sizeof(deviceInfoServiceUUID)); 00131 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID, sizeof(UARTServiceUUID)); 00132 #if defined(TARGET_STM32F411RE) || defined(TARGET_STM32F401RE) 00133 ble.setAdvertisingInterval(1000); 00134 #else 00135 ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000)); 00136 #endif 00137 ble.startAdvertising(); 00138 } 00139 00140 // BLE send data 00141 int ble_send_data(uint8_t *data,int data_len) 00142 { 00143 int sent = 0; 00144 00145 /* 00146 DBG("in ble_send_data() data_len=%d data: [",data_len); 00147 for(int i=0;i<data_len;++i) { 00148 DBG("%.2x",data[i]); 00149 if (i < (data_len-1)) DBG(" "); 00150 } 00151 DBG("] sent: "); 00152 */ 00153 00154 sent = ble_rpc_send_data(data,data_len); 00155 //DBG("%d bytes\r\n",sent); 00156 DBG("ble_send_data(): sent %d bytes...\r\n",sent); 00157 return sent; 00158 } 00159 00160 // BLE recv data 00161 int ble_recv_data(uint8_t *buffer,int buffer_len) 00162 { 00163 int recv = ble_rpc_recv_data(buffer,buffer_len); 00164 00165 /* 00166 DBG("in ble_recv_data() recv=%d data: [",recv); 00167 for(int i=0;i<recv;++i) { 00168 DBG("%.2x",buffer[i]); 00169 if (i < (recv-1)) DBG(" "); 00170 } 00171 DBG("] buffer_len=%d\r\n",buffer_len); 00172 */ 00173 DBG("in ble_recv_data() received %d bytes...\r\n",recv); 00174 00175 return recv; 00176 } 00177 00178 // plumb out the network 00179 void net_stubs_pre_plumb_network(bool canActAsRouterNode) 00180 { 00181 // BLE initialize... 00182 DBG("Initializing BLE...\r\n"); 00183 ble_init(); 00184 } 00185 00186 // called after the endpoint is configured... 00187 void net_stubs_post_plumb_network(void) 00188 { 00189 // Initialize the BLE RPC layer 00190 DBG("Initializing BLE UART RPC layer...\r\n"); 00191 ble_rpc_init(ble); 00192 00193 // BLE advertise... 00194 DBG("Beginning BLE advertising...\r\n"); 00195 ble_begin_advertising(); 00196 } 00197 00198 // create a suitable main event loop for this specific network 00199 void net_stubs_create_main_loop(void) 00200 { 00201 // nothing to do for BLE endpoints - we are using the Ticker-based loop in nsdl_support.cpp 00202 ; 00203 } 00204 00205 // register the endpoint 00206 void net_stubs_register_endpoint(void) 00207 { 00208 // not used.. must wait until we get a BLE connect callback.. then register... 00209 ; 00210 } 00211 00212 // begin the main loop for processing network events 00213 void net_stubs_begin_main_loop(void) 00214 { 00215 // NDSL main loop 00216 DBG("Beginning NSDL Main Event Loop...\r\n"); 00217 nsdl_event_loop(); 00218 } 00219 00220 }
Generated on Sun Jul 17 2022 05:11:06 by 1.7.2