title: How can I create an Android BLE peripheral?
body: <p>I try to make two bluetooth BLE apps:</p>
  
  <ul>
  <li>one central role </li>
  <li>one peripherall</li>
  </ul>
  
  <p>But I have found some problem and my apps crashed.</p>
  
  <p>This is the step which I followed: </p>
  
  <p>1- client set the descriptor      </p>
  
  <pre><code>BluetoothGattDescriptor descriptor = MeasurementCharacteristic.getDescriptor(
                  UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
          descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
          bluetoothGatt.writeDescriptor(descriptor); 
  </code></pre>
  
  <p>2 - The server in onDescriptorWriteRequest set the </p>
  
  <pre><code>MeasurementCharacteristic.setValue(test.getBytes());
  gattserver.notifyCharacteristicChanged(device, MeasurementCharacteristic, false);
  </code></pre>
  
  <p>3 - The client receive this notification and I have done this :</p>
  
  <pre><code>CommandsCharacteristic.setValue(string_value.getBytes());
                  write(CommandsCharacteristic);
  </code></pre>
  
  <p>4 - The server receives this in onCharacteristicWriteRequest and I have done this :</p>
  
  <pre><code>if(uuid.equals(CostantUUid.Commands))
              {
                  .....
                  engineMeasurementCharacteristic.setValue(test.getBytes());
                  ble.getGattServer().notifyCharacteristicChanged(device, MeasurementCharacteristic, false);
              }
  </code></pre>
  
  <p>5- on the client the notifyCharacteristicChanged will be called and we will return to step 3</p>
  
  <p>But sadly the comunication automatically shut down after few message.</p>
  
  <ul>
  <li>client enable descriptor</li>
  <li>server send notification to the client</li>
  <li>client read the new characteristic and re-write to server</li>
  <li>server resend notify to client</li>
  <li>client read send message to client </li>
  <li>the message doesn't arrive...</li>
  </ul>
  
  <p>With the log I have seen that onCharacteristicWrite's function is been called only once in all the app life. Is been called after the message that it doesn't arrive with status 133 , but I don't understand why it not been called after the other messages.  </p>
  
  <pre><code>@Override
                  public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,int status)
                  {
  
                      super.onCharacteristicWrite(gatt, characteristic, status);
  
                      if(status==BluetoothGatt.GATT_SUCCESS)
                      {
                          Log.i("test","GATT SUCCESS");
                      }
                      if(status==BluetoothGatt.GATT_CONNECTION_CONGESTED)
                      {
                          Log.i("test","GATT WRITE connection congested");
                      }
                      if(status==BluetoothGatt.GATT_WRITE_NOT_PERMITTED)
                      {
                          Log.i("test","GATT WRITE not permitted");
                      }
                      if(status==BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH)
                      {
                          Log.i("test","GATT invalid attribute lenght");
                      }
                      if(status==BluetoothGatt.GATT_FAILURE)
                      {
                          Log.i("test","GATT WRITE other errors");
                      }
                      if(status==BluetoothGatt.GATT_CONNECTION_CONGESTED)
                      {
                          Log.i("test","GATT WRITE congested");
                      }
                      if(status==BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION)
                      {
                          Log.i("test","GATT WRITE authentication");
                      }
                      else
                      {
                          Log.i("test","GATT WRITE :"+status);
                      }
                  }
  </code></pre>
  
  <p>central role's log:</p>
  
  <pre><code>    03-30 15:09:22.308: W/BLE(30615): STATE_CONNECTED
  *******
  *******
  03-30 15:09:50.958: D/HeadsetStateMachine(2312): Disconnected process message: 10
  03-30 15:09:50.958: D/KeyguardUpdateMonitor(1026): received broadcast android.intent.action.BATTERY_CHANGED
  03-30 15:09:50.958: D/KeyguardUpdateMonitor(1026): handleBatteryUpdate
  03-30 15:09:50.958: D/BatteryService(795): level:64, scale:100, status:3, health:2, present:true, voltage: 3898, temperature: 283, technology: Li-ion, AC powered:false, USB powered:false, Wireless powered:false, icon:17303543, invalid charger:0, online:1, current avg:-242, charge type:0, power sharing:false
  03-30 15:09:50.958: D/BatteryService(795): Sending ACTION_BATTERY_CHANGED.
  03-30 15:09:50.958: D/STATUSBAR-PhoneStatusBar(1026):  mBrightnessEnablebySettings = true mBrightnessEnablebyBattery = true mBrightnessEnablebyDisableFlag = true mPmsBrightnessEnablebySettings = true
  03-30 15:09:50.958: D/BatteryMeterView(1026): ACTION_BATTERY_CHANGED : level:64 status:3 health:2
  03-30 15:09:50.968: D/STATUSBAR-IconMerger(1026): checkOverflow(2112), More:false, Req:false Child:2
  03-30 15:09:52.978: D/SensorService(795):   0.0 -0.1 9.9
  03-30 15:09:55.158: D/bt_vendor(2312): op for 7
  03-30 15:09:55.158: D/bt_upio(2312): proc btwrite assertion
  03-30 15:09:55.178: D/SSRMv2:SIOP(795): SIOP:: AP = 300, Delta = 0
  03-30 15:09:55.188: E/bt-btm(2312): btm_sec_disconnected - Clearing Pending flag
  03-30 15:09:55.188: D/IOP_DB_BT(2312): db_query_create: id DisablePwlCtrReq :: key KEY_BDADDR, value 4b:87:e8:45:76:b9
  03-30 15:09:55.188: D/IOP_DB_BT(2312): db_query_add_key: key KEY_LMP_MFCT, value 0
  03-30 15:09:55.188: D/IOP_DB_BT(2312): db_query_add_key: key KEY_LMP_VER, value 0:0
  03-30 15:09:55.188: D/IOP_DB_BT(2312): db_query_add_key: key KEY_DIR_ALL, value *
  03-30 15:09:55.188: D/IOP_DB_BT(2312): db_query_execute: result 1
  03-30 15:09:55.188: D/BtGatt.btif(2312): btif_gattc_upstreams_evt: Event 4
  03-30 15:09:55.188: D/BtGatt.GattService(2312): onWriteCharacteristic() - address=4B:87:E8:45:76:B9, status=133
  03-30 15:09:55.188: D/BluetoothGatt(30615): onCharacteristicWrite() - Device=4B:87:E8:45:76:B9 UUID=687bf0f0-d6dc-11e4-b9d6-1681e6b88ec1 Status=133
  03-30 15:09:55.188: D/BtGatt.btif(2312): btif_gattc_upstreams_evt: Event 5
  03-30 15:09:55.188: D/BtGatt.GattService(2312): onDisconnected() - clientIf=6, connId=6, address=4B:87:E8:45:76:B9
  03-30 15:09:55.188: D/BluetoothGatt(30615): onClientConnectionState() - status=0 clientIf=6 device=4B:87:E8:45:76:B9
  03-30 15:09:55.188: I/*****(30615): status = 0 newState = 0
  03-30 15:09:55.188: W/BLE(30615): STATE_DISCONNECTED
  </code></pre>
  
  <p>Peripheral log:</p>
  
  <pre><code>03-30 15:09:24.001: D/MyActivity(10354): onCharacteristicReadRequest requestId=3 offset=00002a24-0000-1000-8000-00805f9b34fb
  03-30 15:09:24.003: D/BtGatt.btif(9706): btif_gatts_send_response
  03-30 15:09:24.003: D/BtGatt.btif(9706): btgatts_handle_event: Event 2012
  03-30 15:09:24.003: D/BtGatt.GattService(9706): onResponseSendCompleted() handle=46
  03-30 15:09:24.096: D/BtGatt.btif(9706): btapp_gatts_handle_cback: Event 1
  03-30 15:09:24.097: D/BtGatt.GattService(9706): onAttributeRead() UUID=00002a27-0000-1000-8000-00805f9b34fb, serverIf=5, type=2
  03-30 15:09:24.097: D/MyActivity(10354): onCharacteristicReadRequest requestId=4 offset=00002a27-0000-1000-8000-00805f9b34fb
  03-30 15:09:24.098: D/BtGatt.btif(9706): btif_gatts_send_response
  03-30 15:09:24.098: D/BtGatt.btif(9706): btgatts_handle_event: Event 2012
  03-30 15:09:24.098: D/BtGatt.GattService(9706): onResponseSendCompleted() handle=48
  03-30 15:09:24.243: D/BtGatt.btif(9706): btapp_gatts_handle_cback: Event 2
  03-30 15:09:24.243: D/BtGatt.GattService(9706): onAttributeWrite() UUID=00002902-0000-1000-8000-00805f9b34fb, serverIf=5, type=3
  03-30 15:09:24.246: D/BtGatt.btif(9706): btif_gatts_send_response
  03-30 15:09:24.246: D/BtGatt.btif(9706): btgatts_handle_event: Event 2012
  03-30 15:09:24.246: D/BtGatt.GattService(9706): onResponseSendCompleted() handle=52
  03-30 15:09:24.249: D/BtGatt.btif(9706): btif_gatts_send_indication
  03-30 15:09:24.252: D/BtGatt.btif(9706): btgatts_handle_event: Event 2011
  03-30 15:09:24.257: D/BtGatt.btif(9706): btapp_gatts_handle_cback: Event 5
  03-30 15:09:24.257: D/BtGatt.GattService(9706): onNotificationSent() connId=5, status=0
  03-30 15:09:24.341: D/BtGatt.btif(9706): btapp_gatts_handle_cback: Event 2
  03-30 15:09:24.341: D/BtGatt.GattService(9706): onAttributeWrite() UUID=687bf0f0-d6dc-11e4-b9d6-1681e6b88ec1, serverIf=5, type=2
  03-30 15:09:24.342: D/MyActivity(10354): onCharacteristicWriteRequest requestId=6 offset=687bf0f0-d6dc-11e4-b9d6-1681e6b88ec1
  03-30 15:09:24.343: I/test(10354): Message received ciao 
  03-30 15:09:24.344: D/BtGatt.btif(9706): btif_gatts_send_indication
  03-30 15:09:24.345: D/BtGatt.btif(9706): btgatts_handle_event: Event 2011
  03-30 15:09:24.345: D/BtGatt.btif(9706): btapp_gatts_handle_cback: Event 5
  03-30 15:09:24.345: D/BtGatt.GattService(9706): onNotificationSent() connId=5, status=0
  03-30 15:09:54.518: W/bt-btif(9706): bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0013
  03-30 15:09:54.518: W/bt-btif(9706): bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0013
  03-30 15:09:54.519: W/bt-btif(9706): bta_gattc_conn_cback() - cif=6 connected=0 conn_id=6 reason=0x0013
  03-30 15:09:54.519: E/bt-btm(9706): btm_sec_disconnected - Clearing Pending flag
  03-30 15:09:54.519: D/BtGatt.btif(9706): btapp_gatts_handle_cback: Event 15
  03-30 15:09:54.519: D/BtGatt.GattService(9706): onConnected() connId=5, address=B8:6C:E8:5A:99:D2, connected=false
  03-30 15:09:54.520: E/BluetoothRemoteDevices(9706): aclStateChangeCallback: Device is NULL
  03-30 15:09:54.521: D/BluetoothGattServer(10354): onServerConnectionState() - status=0 serverIf=5 device=B8:6C:E8:5A:99:D2
  03-30 15:09:54.522: D/MyActivity(10354): onConnectionStateChange status=0-&gt;0
  03-30 15:09:59.001: E/WifiStateMachine(449): WifiStateMachine CMD_START_SCAN source -2 txSuccessRate=0.69 rxSuccessRate=23.35 targetRoamBSSID=any RSSI=-69
  03-30 15:10:02.207: D/HeadsetStateMachine(9706): Disconnected process message: 10, size: 0
  03-30 15:10:19.001: E/WifiStateMachine(449): WifiStateMachine CMD_START_SCAN source -2 txSuccessRate=0.78 rxSuccessRate=22.32 targetRoamBSSID=any RSSI=-68
  03-30 15:10:38.999: E/WifiStateMachine(449): WifiStateMachine CMD_START_SCAN source -2 txSuccessRate=0.32 rxSuccessRate=34.32 targetRoamBSSID=any RSSI=-67
  </code></pre>
  
  <p><strong>EDIT :</strong> I have cleaned the precedent message with the add of all of your suggestion/advice :)</p>
  
  <p>EDIT 2 : The peripherall still alive, but disconnected. If I reconnect the connection restart, and redo the same step above :(</p>
  
  <p><strong>EDIT3</strong> : on the peripherall I have setted in this way :</p>
  
  <pre><code>settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED);
      settingsBuilder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH);
      settingsBuilder.setConnectable(true);
  </code></pre>
  
  <p>EDIT5 : I solve my problem. There was an error inside OnCharacteristicWriteRequest inside peripherall. The app still working but the connection was crashing. :) </p>
  
  <p>EDIT6 : How can retrieve the real MAC address of my peripherall ? Because on the client side when I use "getAddress()" the MAC address changes each time the peripherall reboots</p>