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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers network_stubs.cpp Source File

network_stubs.cpp

Go to the documentation of this file.
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 }