Core Bluetooth spowalnia podczas wysyłania pakietów
Mam problem, w którym czas między zapisaniem wartości do charakterystyki przy użyciu
[peripheral writeValue:dataPacket forCharacteristic:writeChar type:CBCharacteristicWithResponse]
a urządzenie iOS faktycznie wysyłające pakiet bluetooth stopniowo i coraz dłużej trwa.
Można to zilustrować na następującym wyjściu debuggera:
2013-10-23 14:12:17.510 Test App iOS[1561:60b] Packet sent
2013-10-23 14:12:17.595 Test App iOS[1561:60b] Packet sent confirmation, error = (null)
2013-10-23 14:12:17.598 Test App iOS[1561:60b] Packet response received
2013-10-23 14:12:17.611 Test App iOS[1561:60b] Packet sent
2013-10-23 14:12:17.656 Test App iOS[1561:60b] Packet sent confirmation, error = (null)
2013-10-23 14:12:17.657 Test App iOS[1561:60b] Packet response received
2013-10-23 14:12:22.601 Test App iOS[1561:60b] Packet sent
2013-10-23 14:12:23.123 Test App iOS[1561:60b] Packet sent confirmation, error = (null)
2013-10-23 14:12:23.125 Test App iOS[1561:60b] Packet response received
2013-10-23 14:12:27.601 Test App iOS[1561:60b] Packet sent
2013-10-23 14:12:28.111 Test App iOS[1561:60b] Packet sent confirmation, error = (null)
2013-10-23 14:12:28.113 Test App iOS[1561:60b] Packet response received
2013-10-23 14:12:32.611 Test App iOS[1561:60b] Packet sent
2013-10-23 14:12:34.595 Test App iOS[1561:60b] Packet sent confirmation, error = (null)
2013-10-23 14:12:34.597 Test App iOS[1561:60b] Packet response received
2013-10-23 14:12:37.611 Test App iOS[1561:60b] Packet sent
2013-10-23 14:12:39.582 Test App iOS[1561:60b] Packet sent confirmation, error = (null)
2013-10-23 14:12:39.585 Test App iOS[1561:60b] Packet response received
2013-10-23 14:12:42.611 Test App iOS[1561:60b] Packet sent
2013-10-23 14:12:44.570 Test App iOS[1561:60b] Packet sent confirmation, error = (null)
2013-10-23 14:12:44.573 Test App iOS[1561:60b] Packet response received
2013-10-23 14:12:47.611 Test App iOS[1561:60b] Packet sent
2013-10-23 14:12:49.558 Test App iOS[1561:60b] Packet sent confirmation, error = (null)
2013-10-23 14:12:49.560 Test App iOS[1561:60b] Packet response received
// Several packets omitted...
2013-10-23 14:13:07.610 Test App iOS[1561:60b] Packet sent
2013-10-23 14:13:09.508 Test App iOS[1561:60b] Packet sent confirmation, error = (null)
2013-10-23 14:13:09.511 Test App iOS[1561:60b] Packet response received
2013-10-23 14:13:12.610 Test App iOS[1561:60b] Packet sent
2013-10-23 14:13:14.496 Test App iOS[1561:60b] Packet sent confirmation, error = (null)
2013-10-23 14:13:14.498 Test App iOS[1561:60b] Packet response received
// I tak dalej...
Wiadomość wysłana przez pakiet jest wyprowadzana w linii bezpośrednio po poleceniu writeValue, aby zapisać pakiet danych do charakterystyki.
Potwierdzenie wysłanego pakietu jest wyprowadzane w pierwszej linii w metodzie didWriteValueForCharacteristic.
Komunikat odebrania odpowiedzi pakietu jest wyprowadzany w didUpdateValueForCharacteristic, który jest wywoływany, gdy urządzenie BTLE wysyła pakiet odpowiedzi (za pośrednictwem drugorzędnej charakterystyki powiadomienia) w celu potwierdzenia odbioru mojego wysłanego pakietu.
Jak widać początkowo, czas między wywołaniem metody writeValue forCharacteristic a wywołaniem zwrotnym w celu potwierdzenia, że pakiet został wysłany w didWriteValueForCharacteristic wynosi początkowo 85ms (co jest już powolne, ale znośne). Wysyłam te pakiety co około 5 sekund, a po wysłaniu tylko niewielkiej liczby pakietów zwiększa się to do ~ 2 sekund, po których wydaje się, że jest stale statyczne po 2 sekundach. Pakiet odpowiedzi wysłany z urządzenia BTLE jest zawsze ~ 2 ms po potwierdzeniu wysłania pakietu.
Nie rozumiem, dlaczego otrzymuję to opóźnienie w bibliotekach CoreBluetooth między wywołaniem writeValue a potwierdzeniem zwrotnym didWriteValueForCharacteristic.
Pod wszystkimi innymi względami kod działa doskonale (urządzenie BTLE robi dokładnie to, o co ma polecenie, a żaden z pakietów nie zniknie).
Mam przykładową aplikację dostarczoną przez producenta modułu BT4.0 (w tym źródło), która nie doświadcza tego narastającego opóźnienia - niestety przykładowa aplikacja jest zaprojektowana do radzenia sobie z szerokim zakresem implementacji modułu, a nie tylko z naszą konkretną implementacją jest więc bardzo złożony, zawiera wiele kodu, który po prostu nie ma znaczenia dla naszej implementacji - umieściłem punkty przerwania w każdej funkcji w próbce i przeszedłem ręcznie, aby dokładnie określić, które polecenia wydają, i wierzę, że kopiuję je doskonale ( ale oczywiście nie).
Nic nie widzę, co robią, czego nie robię i odwrotnie. Jedyną różnicą, jaką mogę zauważyć między dwoma projektami, jest to, że kopalnia korzysta z ARC, a ich używa ręcznego liczenia referencji.
Inne informacje: Wszystko działa na głównym wątku (tak jak w przypadku przykładowej aplikacji producentów modułów) Tworzę Central Managera za pomocą głównej kolejki (podobnie w przykładowej aplikacji producentów modułów) Obciążenie procesora na urządzeniu z systemem iOS wynosi tylko 3% podczas moja aplikacja działa i nic nie jest opóźnione z powodu obciążenia procesora itp.
Wyrywam sobie z tego włosy i jeśli ktoś może zasugerować możliwe przyczyny lub rozwiązania tego problemu, byłbym wiecznie wdzięczny!
Dzięki, Rich