// +build softdevice,!s110v8 package bluetooth /* // Define SoftDevice functions as regular function declarations (not inline // static functions). #define SVCALL_AS_NORMAL_FUNCTION #include "nrf_sdm.h" #include "ble.h" #include "ble_gap.h" void assertHandler(void); */ import "C" import "unsafe" //export assertHandler func assertHandler() { println("SoftDevice assert") } var clockConfig C.nrf_clock_lf_cfg_t = C.nrf_clock_lf_cfg_t{ source: C.NRF_CLOCK_LF_SRC_SYNTH, rc_ctiv: 0, rc_temp_ctiv: 0, accuracy: 0, } func (a *Adapter) enable() error { // Enable the SoftDevice. errCode := C.sd_softdevice_enable(&clockConfig, C.nrf_fault_handler_t(C.assertHandler)) if errCode != 0 { return Error(errCode) } // Enable the BLE stack. appRAMBase := uint32(0x200039c0) errCode = C.sd_ble_enable(&appRAMBase) return makeError(errCode) } func handleEvent() { id := eventBuf.header.evt_id switch { case id >= C.BLE_GAP_EVT_BASE && id <= C.BLE_GAP_EVT_LAST: gapEvent := eventBuf.evt.unionfield_gap_evt() switch id { case C.BLE_GAP_EVT_CONNECTED: // This event is ignored for now. It might be useful for the API // user, but until there is a good use case it's best left out. case C.BLE_GAP_EVT_DISCONNECTED: if defaultAdvertisement.isAdvertising.Get() != 0 { // The advertisement was running but was automatically stopped // by the connection event. // Note that it cannot be restarted during connect like this, // because it would need to be reconfigured as a non-connectable // advertisement. That's left as a future addition, if // necessary. C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT) } // Ignore this event otherwise. case C.BLE_GAP_EVT_ADV_REPORT: advReport := gapEvent.params.unionfield_adv_report() if debug && &scanReportBuffer.data[0] != advReport.data.p_data { // Sanity check. panic("scanReportBuffer != advReport.p_data") } // Prepare the globalScanResult, which will be passed to the // callback. scanReportBuffer.len = byte(advReport.data.len) globalScanResult.RSSI = int16(advReport.rssi) globalScanResult.Address = advReport.peer_addr.addr globalScanResult.AdvertisementPayload = &scanReportBuffer // Signal to the main thread that there was a scan report. // Scanning will be resumed (from the main thread) once the scan // report has been processed. gotScanReport.Set(1) case C.BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: // Respond with the default PPCP connection parameters by passing // nil: // > If NULL is provided on a peripheral role, the parameters in the // > PPCP characteristic of the GAP service will be used instead. If // > NULL is provided on a central role and in response to a // > BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request // > will be rejected C.sd_ble_gap_conn_param_update(gapEvent.conn_handle, nil) case C.BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: // We need to respond with sd_ble_gap_data_length_update. Setting // both parameters to nil will make sure we send the default values. C.sd_ble_gap_data_length_update(gapEvent.conn_handle, nil, nil) default: if debug { println("unknown GAP event:", id) } } case id >= C.BLE_GATTS_EVT_BASE && id <= C.BLE_GATTS_EVT_LAST: gattsEvent := eventBuf.evt.unionfield_gatts_evt() switch id { case C.BLE_GATTS_EVT_WRITE: writeEvent := gattsEvent.params.unionfield_write() len := writeEvent.len - writeEvent.offset data := (*[255]byte)(unsafe.Pointer(&writeEvent.data[0]))[:len:len] handler := DefaultAdapter.getCharWriteHandler(writeEvent.handle) if handler != nil { handler.callback(Connection(gattsEvent.conn_handle), int(writeEvent.offset), data) } case C.BLE_GATTS_EVT_SYS_ATTR_MISSING: // This event is generated when reading the Generic Attribute // service. It appears to be necessary for bonded devices. // From the docs: // > If the pointer is NULL, the system attribute info is // > initialized, assuming that the application does not have any // > previously saved system attribute data for this device. // Maybe we should look at the error, but as there's not really a // way to handle it, ignore it. C.sd_ble_gatts_sys_attr_set(gattsEvent.conn_handle, nil, 0, 0) case C.BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: // This event is generated by some devices. While we could support // larger MTUs, this default MTU is supported everywhere. C.sd_ble_gatts_exchange_mtu_reply(gattsEvent.conn_handle, C.BLE_GATT_ATT_MTU_DEFAULT) default: if debug { println("unknown GATTS event:", id, id-C.BLE_GATTS_EVT_BASE) } } default: if debug { println("unknown event:", id) } } }