Guest User

Untitled

a guest
Dec 14th, 2017
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.54 KB | None | 0 0
  1. //This is the BLE Central Class
  2. import Foundation
  3. import UIKit
  4. import CoreBluetooth
  5.  
  6.  
  7. var txCharacteristic : CBCharacteristic?
  8. var rxCharacteristic : CBCharacteristic?
  9. var blePeripheral : CBPeripheral?
  10. var characteristicASCIIValue = NSString()
  11.  
  12.  
  13.  
  14. class BLECentralViewController : UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate, UITableViewDelegate, UITableViewDataSource{
  15.  
  16. //Data
  17. var centralManager : CBCentralManager!
  18. var RSSIs = [NSNumber]()
  19. var data = NSMutableData()
  20. var writeData: String = ""
  21. var peripherals: [CBPeripheral] = []
  22. var characteristicValue = [CBUUID: NSData]()
  23. var timer = Timer()
  24. var characteristics = [String : CBCharacteristic]()
  25.  
  26. //UI
  27. @IBOutlet weak var baseTableView: UITableView!
  28. @IBOutlet weak var refreshButton: UIBarButtonItem!
  29.  
  30. @IBAction func refreshAction(_ sender: AnyObject) {
  31. disconnectFromDevice()
  32. self.peripherals = []
  33. self.RSSIs = []
  34. self.baseTableView.reloadData()
  35. startScan()
  36. }
  37.  
  38. override func viewDidLoad() {
  39. super.viewDidLoad()
  40. self.baseTableView.delegate = self
  41. self.baseTableView.dataSource = self
  42. self.baseTableView.reloadData()
  43.  
  44. centralManager = CBCentralManager(delegate: self, queue: nil)
  45.  
  46. let backButton = UIBarButtonItem(title: "Disconnect", style: .plain, target: nil, action: nil)
  47. navigationItem.backBarButtonItem = backButton
  48. }
  49.  
  50. override func viewDidAppear(_ animated: Bool) {
  51. disconnectFromDevice()
  52. super.viewDidAppear(animated)
  53. refreshScanView()
  54. print("View Cleared")
  55. }
  56.  
  57. override func viewWillDisappear(_ animated: Bool) {
  58. super.viewWillDisappear(animated)
  59. print("Stop Scanning")
  60. centralManager?.stopScan()
  61. }
  62.  
  63. /*Okay, now that we have our CBCentalManager up and running, it's time to start searching for devices. You can do this by calling the "scanForPeripherals" method.*/
  64.  
  65. func startScan() {
  66. peripherals = []
  67. print("Now Scanning...")
  68. self.timer.invalidate()
  69. centralManager?.scanForPeripherals(withServices: [BLEService_UUID] , options: [CBCentralManagerScanOptionAllowDuplicatesKey:false])
  70. Timer.scheduledTimer(timeInterval: 17, target: self, selector: #selector(self.cancelScan), userInfo: nil, repeats: false)
  71. }
  72.  
  73. /*We also need to stop scanning at some point so we'll also create a function that calls "stopScan"*/
  74. func cancelScan() {
  75. self.centralManager?.stopScan()
  76. print("Scan Stopped")
  77. print("Number of Peripherals Found: (peripherals.count)")
  78. }
  79.  
  80. func refreshScanView() {
  81. baseTableView.reloadData()
  82. }
  83.  
  84. //-Terminate all Peripheral Connection
  85. /*
  86. Call this when things either go wrong, or you're done with the connection.
  87. This cancels any subscriptions if there are any, or straight disconnects if not.
  88. (didUpdateNotificationStateForCharacteristic will cancel the connection if a subscription is involved)
  89. */
  90. func disconnectFromDevice () {
  91. if blePeripheral != nil {
  92. // We have a connection to the device but we are not subscribed to the Transfer Characteristic for some reason.
  93. // Therefore, we will just disconnect from the peripheral
  94. centralManager?.cancelPeripheralConnection(blePeripheral!)
  95. }
  96. }
  97.  
  98.  
  99. func restoreCentralManager() {
  100. //Restores Central Manager delegate if something went wrong
  101. centralManager?.delegate = self
  102. }
  103.  
  104.  
  105. func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,advertisementData: [String : Any], rssi RSSI: NSNumber) {
  106.  
  107. blePeripheral = peripheral
  108. self.peripherals.append(peripheral)
  109. self.RSSIs.append(RSSI)
  110. peripheral.delegate = self
  111. self.baseTableView.reloadData()
  112. if blePeripheral == nil {
  113. print("Found new pheripheral devices with services")
  114. print("Peripheral name: (String(describing: peripheral.name))")
  115. print("**********************************")
  116. print ("Advertisement Data : (advertisementData)")
  117. }
  118. }
  119.  
  120. //Peripheral Connections: Connecting, Connected, Disconnected
  121.  
  122. //-Connection
  123. func connectToDevice () {
  124. centralManager?.connect(blePeripheral!, options: nil)
  125. }
  126.  
  127.  
  128. //-Connected
  129. func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
  130. print("*****************************")
  131. print("Connection complete")
  132. print("Peripheral info: (String(describing: blePeripheral))")
  133.  
  134. //Stop Scan- We don't need to scan once we've connected to a peripheral. We got what we came for.
  135. centralManager?.stopScan()
  136. print("Scan Stopped")
  137.  
  138. //Erase data that we might have
  139. data.length = 0
  140.  
  141. //Discovery callback
  142. peripheral.delegate = self
  143. //Only look for services that matches transmit uuid
  144. peripheral.discoverServices([BLEService_UUID])
  145.  
  146.  
  147. //Once connected, move to new view controller to manager incoming and outgoing data
  148. let storyboard = UIStoryboard(name: "Main", bundle: nil)
  149.  
  150. let firstVC = storyboard.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
  151.  
  152. firstVC.peripheral = peripheral
  153.  
  154. navigationController?.pushViewController(firstVC, animated: true)
  155. }
  156.  
  157.  
  158.  
  159. func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
  160. if error != nil {
  161. print("Failed to connect to peripheral")
  162. return
  163. }
  164. }
  165.  
  166. func disconnectAllConnection() {
  167. centralManager.cancelPeripheralConnection(blePeripheral!)
  168. }
  169.  
  170.  
  171. func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
  172. print("*******************************************************")
  173.  
  174. if ((error) != nil) {
  175. print("Error discovering services: (error!.localizedDescription)")
  176. return
  177. }
  178.  
  179. guard let services = peripheral.services else {
  180. return
  181. }
  182. //We need to discover the all characteristic
  183. for service in services {
  184.  
  185. peripheral.discoverCharacteristics(nil, for: service)
  186. // bleService = service
  187. }
  188. print("Discovered Services: (services)")
  189. }
  190.  
  191.  
  192.  
  193. func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
  194.  
  195. print("*******************************************************")
  196.  
  197. if ((error) != nil) {
  198. print("Error discovering services: (error!.localizedDescription)")
  199. return
  200. }
  201.  
  202. guard let characteristics = service.characteristics else {
  203. return
  204. }
  205.  
  206. print("Found (characteristics.count) characteristics!")
  207.  
  208. for characteristic in characteristics {
  209. //looks for the right characteristic
  210.  
  211. if characteristic.uuid.isEqual(BLE_Characteristic_uuid_Rx) {
  212. rxCharacteristic = characteristic
  213.  
  214. //Once found, subscribe to the this particular characteristic...
  215. peripheral.setNotifyValue(true, for: rxCharacteristic!)
  216. // We can return after calling CBPeripheral.setNotifyValue because CBPeripheralDelegate's
  217. // didUpdateNotificationStateForCharacteristic method will be called automatically
  218. peripheral.readValue(for: characteristic)
  219. print("Rx Characteristic: (characteristic.uuid)")
  220. }
  221. if characteristic.uuid.isEqual(BLE_Characteristic_uuid_Tx){
  222. txCharacteristic = characteristic
  223. print("Tx Characteristic: (characteristic.uuid)")
  224. }
  225. peripheral.discoverDescriptors(for: characteristic)
  226. }
  227. }
  228.  
  229.  
  230. func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
  231.  
  232. if characteristic == rxCharacteristic {
  233. if let ASCIIstring = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue) {
  234. characteristicASCIIValue = ASCIIstring
  235. print("Value Recieved: ((characteristicASCIIValue as String))")
  236. NotificationCenter.default.post(name:NSNotification.Name(rawValue: "Notify"), object: nil)
  237.  
  238. }
  239. }
  240. }
  241.  
  242.  
  243. func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {
  244. print("*******************************************************")
  245.  
  246. if error != nil {
  247. print("(error.debugDescription)")
  248. return
  249. }
  250. if ((characteristic.descriptors) != nil) {
  251.  
  252. for x in characteristic.descriptors!{
  253. let descript = x as CBDescriptor!
  254. print("function name: DidDiscoverDescriptorForChar (String(describing: descript?.description))")
  255. print("Rx Value (String(describing: rxCharacteristic?.value))")
  256. print("Tx Value (String(describing: txCharacteristic?.value))")
  257. }
  258. }
  259. }
  260.  
  261.  
  262. func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
  263. print("*******************************************************")
  264.  
  265. if (error != nil) {
  266. print("Error changing notification state:(String(describing: error?.localizedDescription))")
  267.  
  268. } else {
  269. print("Characteristic's value subscribed")
  270. }
  271.  
  272. if (characteristic.isNotifying) {
  273. print ("Subscribed. Notification has begun for: (characteristic.uuid)")
  274. }
  275. }
  276.  
  277. func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
  278. print("Disconnected")
  279. }
  280.  
  281.  
  282. func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
  283. guard error == nil else {
  284. print("Error discovering services: error")
  285. return
  286. }
  287. print("Message sent")
  288. }
  289.  
  290. func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
  291. guard error == nil else {
  292. print("Error discovering services: error")
  293. return
  294. }
  295. print("Succeeded!")
  296. }
  297.  
  298. //Table View Functions
  299. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  300. return self.peripherals.count
  301. }
  302.  
  303. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  304.  
  305. let cell = tableView.dequeueReusableCell(withIdentifier: "BlueCell") as! PeripheralTableViewCell
  306. let peripheral = self.peripherals[indexPath.row]
  307. let RSSI = self.RSSIs[indexPath.row]
  308.  
  309.  
  310. if peripheral.name == nil {
  311. cell.peripheralLabel.text = "nil"
  312. } else {
  313. cell.peripheralLabel.text = peripheral.name
  314. }
  315. cell.rssiLabel.text = "RSSI: (RSSI)"
  316.  
  317. return cell
  318. }
  319.  
  320. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  321. blePeripheral = peripherals[indexPath.row]
  322. connectToDevice()
  323. }
  324.  
  325.  
  326. func centralManagerDidUpdateState(_ central: CBCentralManager) {
  327. if central.state == CBManagerState.poweredOn {
  328. // We will just handle it the easy way here: if Bluetooth is on, proceed...start scan!
  329. print("Bluetooth Enabled")
  330. startScan()
  331.  
  332. } else {
  333. //If Bluetooth is off, display a UI alert message saying "Bluetooth is not enable" and "Make sure that your bluetooth is turned on"
  334. print("Bluetooth Disabled- Make sure your Bluetooth is turned on")
  335.  
  336. let alertVC = UIAlertController(title: "Bluetooth is not enabled", message: "Make sure that your bluetooth is turned on", preferredStyle: UIAlertControllerStyle.alert)
  337. let action = UIAlertAction(title: "ok", style: UIAlertActionStyle.default, handler: { (action: UIAlertAction) -> Void in
  338. self.dismiss(animated: true, completion: nil)
  339. })
  340. alertVC.addAction(action)
  341. self.present(alertVC, animated: true, completion: nil)
  342. }
  343. }
  344. }
  345.  
  346. //Now the FirstViewController
  347.  
  348.  
  349. class FirstViewController: UIViewController, UIPeripheralManagerDelegate {
  350.  
  351. var peripheralManager: CBPeripheralManager?
  352. var peripheral: CBPeripheral!
  353.  
  354. viewDidLoad(){
  355.  
  356. //I'm calling the blePeripheral from BLE class to the peripheral in the current class
  357. peripheral = blePeripheral
  358.  
  359. }
  360.  
  361. //I have a button here to send some data and only when I receive the data I want to go to the next view controller
  362.  
  363. @IBAction func login(_sender: AnyObject) {
  364. //This is my write code
  365.  
  366. let bytes : [UInt8] = [ 0x1A, 0x2B, 0x3C, 0x4D ]
  367. let Transmitdata = NSData(bytes: bytes, length: bytes.count)
  368. peripheral.writeValue(Transmitdata as Data, for: txCharacteristic!, type: CBCharacteristicWriteType.withoutResponse)
  369. print("Data Sent",Transmitdata)
  370.  
  371. //Give time for data to be received fromdevice
  372. sleep(1)
  373.  
  374.  
  375. //let ReceiveData = rxCharacteristic?.value
  376. if let ReceiveData = ReceiveData {
  377. let ReceivedNoOfBytes = ReceiveData.count
  378. var ReceivedByteArray = [UInt8](repeating: 0, count: ReceivedNoOfBytes)
  379. (ReceiveData as NSData).getBytes(&ReceivedByteArray, length: ReceivedNoOfBytes)
  380. print("Data Received ",ReceivedByteArray)
  381.  
  382.  
  383. //checking if we received the right data?
  384. if(ReceivedByteArray[0] == 10 && ReceivedByteArray[1] == 20 && ReceivedByteArray[2] == 30 && ReceivedByteArray[3] == 40){
  385. performSegue(withIdentifier: "Second_View", sender: self)
  386. }
  387. }
  388.  
  389. }
  390.  
  391. class SecondViewController: UIViewController{
  392.  
  393. var firstview: FirstViewController?
  394.  
  395.  
  396. var peripheralManager: CBPeripheralManager?
  397. var peripheral: CBPeripheral!
  398.  
  399. override func viewWillAppear(_animated: Bool){
  400. let peripheral = firstview?.peripheral
  401. let peripheralManager = firstview?.peripheralManager
  402. }
  403.  
  404.  
  405.  
  406. //I have another button here to direct me to third view controller class
  407.  
  408. @IBAction func mainmenu(_sender: AnyObject){
  409.  
  410.  
  411. //send some bytes
  412.  
  413. //receiver some bytes
  414.  
  415. //similar to the first view controller
  416.  
  417. If correct data is received
  418. {
  419. performSegue(withIdentifier: "Main_M", sender: self)
  420. }
  421. }
  422.  
  423.  
  424. override func prepare(for segue: UIStoryboardSegue, sender: Any?){
  425. if segue.destination is Main_M
  426. {
  427. let gotoM = segue.destination as? Main_M
  428. gotoM?.peripheral = firstview?.peripheral
  429. }
  430. }
Add Comment
Please, Sign In to add comment