Android BLE 파헤치기 _ Auto Connect 편

김다훈·2022년 5월 2일
4

BLE 파헤치기

목록 보기
1/1

서론

나는 현재 회사에서 블루투스 SDK 관련 업무를 맡고 있다. 그래서 블루투스 관련 문서를 많이 보는 편인데, 안드로이드 공식 사이트에 나와있는 블루투스 관련 설명이 하나같이 다 불친절하다고 느꼈다.

사실 문서만이 아니다. 실제로 API를 사용해보면 에러 코드가 별 다른 구분 없이 다 동일한 코드로 떨어진다던가, 블루투스 전송 시 API 레벨에서 일련의 큐 구조와 같은 메시지 관리 로직이 없어 성공, 실패 등등의 응답이 떨어지기 전에 전송하면 문제가 발생한다던가 ...

사실 이러한 내용들은 난 공식 문서에서 알려줘야 하는 부분이라고 생각하는데, 공식 문서에는 하나같이 내용들이 부실하며, 그냥 단순한 코드 스니펫만 줄줄 나와있다.

그래서 답답했던 나머지 내가 여태껏 안드로이드의 Bluetooth API를 사용하면서 이해가 되지 않거나, 궁금했던 내용, 삽질했던 내 기록들을 담은 BLE 시리즈를 준비해보았다.

오늘은 그 첫번째 이야기, Auto Connect에 관한 내용이다.

살펴보기

안드로이드 공식 문서를 확인해보면 다음과 같은 코드 스니펫을 볼 수 있다.

var bluetoothGatt: BluetoothGatt? = null
...
bluetoothGatt = device.connectGatt(this, false, gattCallback)

매개변수는 앞에서부터 Context, boolean, BluetoothGattCallback 를 입력받는다.

Context와 BluetoothGattCallback은 그렇다 쳐도, 2번째 값인 autoConnect(boolean)은 어떤 친구일까?

autoConnect : 이용 가능한 즉시 블루투스 기기에 자동 연결할지 나타내는 부울
Android Developer

그렇다. 번역된거라 이해가 바로 되지는 않지만, 여러 번 읽다 보면 뭔가 자동으로 다시 연결해주고 싶을 때 사용하는 플래그 같다.

이 플래그를 설정하면 어떠한 매커니즘이 동작할까?

Auto Connect와 Direct Connect

위의 매개변수 autoConnect에 전달하는 값에 따라

  • true : Auto Connect
  • false : Direct Connect

로 동작한다.

Direct Connect

용어에서도 알 수 있듯이, 직접 연결을 의미한다.

  • 이 연결은 시스템 설정 앱에서 블루투스 스캔 후 터치하여 직접 연결하는 것과 동일하다.
  • Direct Connect를 이용해 BLE 연결 시도 시, 안드로이드 OS는 30초의 시간 제한을 둔다.
  • 30초 이내 연결이 되지 않을 경우 실패로 간주해, 더 이상 연결을 시도하지 않고 Callback으로 에러를 반환한다.

또한 Direct Connect는 Auto Connect에 비해 우선순위가 높게 처리되기 때문에 만약 Auto Connect를 시도하고 있는 연결이 있다면 잠시 중단하고 Direct Connect를 우선적으로 처리하게 된다.

Auto Connect

이건 자동 연결을 의미하며, Direct Connect의 반대 성격을 가진다.

  • 우선 연결에 시간 제한이 없다. 주변 장치를 계속 스캔하며 연결이 가능해지면 연결을 시도한다.
  • 한 번 연결됐던 디바이스는 사용자의 별 다른 상호작용 없이도 계속 연결을 시도한다.

또한 동시에 여러 개의 Auto Connect 연결을 가질 수 있다. 그래서 디바이스 신호가 약해졌거나, 꺼졌거나 하는 등의 이유로 Connection을 Lost 해도 끊임없이 재연결을 시도한다.

근데, 만약 이 때 disconnect() 또는 close()를 호출하여 연결이 끊어지면 다시 연결을 시도하지 않는다.

차이점

이 외에도 연결할 때 차이가 있다. Direct Connect가 30초라는 시간 제한을 가진 대신 우선순위가 더 높기 때문에 더 짧은 주기로 연결 가능한 Advertising Packet을 검색한다. 그래서 Auto Connect보다 연결이 더 빠르게 성립된다.

사실 이 차이는 Android 10 부터는 줄어들었다고 한다. Direct Connect를 처리하는 동안 Auto Connect는 멈추지 않고, Direct Connect에도 Whitelist 개념이 도입되어 Auto Connect와 비슷하게 동작된다고 한다.

Auto Connect의 동작 방식

autoConnect = true 로 연결이 성립된다면 연결된 디바이스에 대한 정보가 캐시되어 저장된다. 이게 WhiteList에 등록되는 것인데, 무조건 등록되는 것은 아니고 아래의 조건 중 하나 이상을 만족해야 한다.

  • 블루투스 기기와 bind 되어야 한다.
  • 블루투스 기기의 주소가 public 해야 한다.
  • 블루투스 기기의 주소가 random static address 여야 한다.

이 중에 한 가지의 조건도 성립되지 않는다면 whiteList에 추가되지 못하고, 재연결을 시도하지 않게 된다.

Auto Connect의 활용

백그라운드에서 지속적인 연결이 필요한 경우에 사용할 수 있겠다. 나와 같은 경우 개발 중인 SDK 중 백그라운드에서도 지속적인 데이터 수신이 필요한 기능이 있는데, Connection이 항상 유지될 수가 없으므로 이럴 때 Auto Connect를 이용해 다시 연결을 시도하는 방식을 생각해보았다.

다만 백그라운드에서 블루투스 Connection을 유지하기 위해 Foreground Service를 이용해 백그라운드에서도 연결이 유지되도록 작업해주었다.

결론

Auto Connect가 연결이 해제되어도 다시 연결을 해주기 때문에 더 좋아보일 수도 있지만, Direct Connect 보다 우선순위가 낮아 연결이 늦게 성립된다.

또, 앱이 종료되면 디바이스 정보를 캐시했던 WhiteList가 날아가서 재연결을 시도하지 않는다. 이는 활용에서도 언급했듯이 Foreground Service를 이용해 백그라운드에서도 어느 정도의 연결 유지는 가능하다. 다만 이 Service도 시스템에 의하여 종료되는 등의 이유로 앱의 프로세스가 완전히 kill 된다면 재연결을 다시 시도하지 않는다. 이는 단말기가 Shutdown 해도 동일하다.

나와 같은 경우 위의 상황을 대비해 MAC Address를 따로 저장하여 BroadcastReceiver를 통해 부팅 이벤트를 수신받고, Foreground Service를 이용해 재연결 하도록 작업하려고 했다.


참고

https://stackoverflow.com/questions/40156699/which-correct-flag-of-autoconnect-in-connectgatt-of-ble

profile
기록을 남기는 걸 좋아하는 안드로이드 개발자입니다.

1개의 댓글

comment-user-thumbnail
2024년 4월 16일

잘봤습니다.

답글 달기