Спасибо. У китайцев в примерах реализован Client Characteristic Configuration descriptor. Так-же в своих примерах они используют 2 функции - GATTServApp_InitCharCfg и GATTServApp_ReadCharCfg для инициализации и чтения значений этого дескриптора. Функция записи GATTServApp_WriteCharCfg в примерах не используется. Либо китайцы чего-то не доделали в своих примерах, либо библиотека это делает сама.
Но фиг с ними - и с китайцами, и с их библиотеками. Вопрос у меня все-таки остался - что говорит стандарт о необходимости иметь Client Characteristic Configuration descriptor для выдачи нотификаций и индикаций??? Там как-то непонятно написано. Вроде бы он нужен, чтобы клиент мог управлять нотификациями и индикациями, и в то-же время сказано - что он необязателен.
Добрый день. Напишу своё видение этого вопроса. Я согласен с
pvvx в том, что многое зависит от конкретной реализации SDK. Давайте взглянем на этот вопрос с физической стороны. Что такое подпись на нотификацию? Это разрешение серверу ( чаще всего датчику ) отправлять клиенту ( чаще всего смартфон) сообщения об изменении параметра САМОСТОЯТЕЛЬНО. Т.е. без запроса со стороны самого клиента. Но что происходит на физическом уровне? После того как клиент увидел сервер в режиме advertising-а и присоединил его, у нас на рабочих каналах регулярно происходит запрос-ответ между клиентом (мастер) и сервером (slave). Т.е. что бы поддерживать связь, два устройства выходят в эфир и обмениваются друг с другом пакетами, чаще всего пустыми. Это физический уровень. Он нужен для поддержания связи. Если смартфону (мастер) надо передать запрос на датчик (slave) пакет от смартфона будет уже не пустым. Это запрос имеет свойства GATT_PROP_WRITE_NO_RSP или GATT_PROP_WRITE. В последнем случае датчик (slave) формирует ответ на запрос и через некоторое время передает его обратно. Но работать по запросу не всегда удобно, поэтому если подписаться на нотификацию, то датчик сам может посылать не пустой пакет смартфону (мастеру) на его пустой пакет. Вот здесь и кроются нюансы. Объясню. Что бы обратный пакет был принят, необходимо, что бы slave готов был его отправлять (был такой механизм у него, функции прописаны, выделены буферы и прочее), а master готов был его принимать (то же что бы был механизм). Поэтому когда делается подпись на нотификацию, master подготавливает механизм приема (если он ранее не был подготовлен), а затем отправляет команду на slave, что бы и он включил у себя механизм передачи без запроса. Так говорит теория. В жизни же всё может быть немного по другому. У slave как правило нет двух отдельных механизмов ответа - с запросом и самостоятельно (нотификация), как и у master нет двух разных механизмов приема. Различие только в заголовках пакетов. Через эти заголовки мы можем понять что это - ответ на запрос или нотификация. Что в большинстве случаев всё равно. Дальше обработка одинакова. Вам, к примеру, без разницы как градусник прислал температуру, по запросу или самостоятельно, обработка далее будет одинаковой. Поэтому эта игра в нотификацию часто условна., поэтому и пишут что Client Characteristic Configuration descriptor - это необязательный дескриптор . Я на одном из своих изделий WCH сделал отправку нотификации по нажатию кнопки, но при этом не делал никакой обработки подписи на нотификацию. Т.е. считаю что она сделана по-умолчанию. При открытии на телефоне программы nRF Connect и присоединении к телефону моего девайса, я могу отправлять на телефон уведомление о нажатии кнопки. И программа nRF Connect видит эти уведомления, хотя подпись на нотификацию не активна. Однако я встречал в своей практике случаи, когда без подписи на нотификацию, сама нотификация не работала. Так что повторюсь, как сказал
pvvx это во многом зависит от конкретной реализаwии SDK. Посмотри мои 2 статьи на Хабре на тему GATT, там то же об этом я писал.
https://habr.com/ru/articles/505078/ https://habr.com/ru/articles/735162/