К сожалению 802.11 как стандарт не имеет явных требований к критериям выбора кандидата для миграции, в итоге каждый чипмэйкер (а то и вендор) реализует этот момент в силу своей фантазии.
Этим и обусловлено различное поведение при миграции от устройства к устройству.
Сегодня рассмотрим один из вариантов на примере кода клиентов от MTK.
Этот код используется в проприетарных драйверах МТК (почти все планшеты и телефоны на МТК используют именно такие драйвера). Смыл его в том, что бы выбрать из списка сканирования кандидата для переключения/миграции.
Т.е. именно выбор такой ТД на которую мы с большой долей вероятности сможем максимально безболезненно и с наименьшими затратами времени “прыгнуть”.
Не когда, а куда… Вот в чём вопрос… ;)
Функция FT_CheckForRoaming (используется в случае поддержки 802.11r с обеих сторон). Опустим все объявления и т.д. оставим только условия.
if (pBss->bHasMDIE == FALSE) continue; /* skip legacy AP */ if (pApEntry && MAC_ADDR_EQUAL(pBss->Bssid, pApEntry->Addr)) continue; /* skip current AP */ if (!FT_MDID_EQU(pBss->FT_MDIE.MdId, pAd->StaCfg[0].Dot11RCommInfo.MdIeInfo.MdId)) continue; /* skip different MDID */ if ((pBss->Rssi <= -85) && (pBss->Channel == wdev->channel)) continue; /* skip RSSI too weak at the same channel */ if ((pBss->Channel != wdev->channel) && (pBss->FT_MDIE.FtCapPlc.field.FtOverDs == FALSE)) continue; /* skip AP in different channel without supporting FtOverDs */ max_rssi = RTMPMaxRssi(pAd, pAd->StaCfg[0].RssiSample.LastRssi[0], pAd->StaCfg[0].RssiSample.LastRssi[1], pAd->StaCfg[0].RssiSample.LastRssi[2]); if (pBss->Rssi < (max_rssi + RSSI_DELTA)) continue; /* skip AP without better RSSI */ if ((pBss->AKMMap != wdev->SecConfig.AKMMap) || (pBss->PairwiseCipher != wdev->SecConfig.PairwiseCipher)) continue; /* skip different Security Setting */
И так. Мы в цикле (здесь он опущен, весь код выше собственно в теле цикла) перебираем всех кандидатов (они уже отсортированы по уровню) перемещая оных в отдельный массив. А выше условия исключения из подходящих.
1) пропускаем все ТД которые не анонсируют Mobile Domain
2) пропускаем собственную ТД (т.к. наш адаптер может быть и точкой доступа и клиентом одновременно)
3) пропускаем ТД с отличным от текущего MobileDomain
4) сразу отфильтровываем все ТД с уровнями ниже -85 работающих на том же канале, что и текущая
5) пропускаем ТД работающие на смежных каналах без поддержки Fast Transition Roaming over DS (подробнее о FT)
6) берём rssi, тот с которым слышим текущую ТД, и если у кандидата RSSI ниже чем текущий RSSI + 5dBm выбраковываем и его
7) ну и наконец сравниваем настройки шифрования и аутентификации, любое отличие в них приведёт к отказу в использовании FT для роуминга
Едем дальше. А что если не нашлось кандидата для миграции с FT (802.11r)? Для этого есть отдельная логика которая попытается подобрать нам кандидата для миграции без использования 802.11r (да,сама фаза переключения будет чуть дольше т.к. фаза аутентификации должна быть снова пройдена целиком).
Функция MlmeCheckForFastRoaming (так же опущено всё кроме критериев, тут их меньше):
if ((pBss->Rssi <= -50) && (pBss->Channel == wdev->channel)) continue; /* RSSI too weak. forget it.*/ if (MAC_ADDR_EQUAL(pBss->Bssid, pStaCfg->Bssid)) continue; /* skip current AP*/ if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pStaCfg->Ssid, pStaCfg->SsidLen)) continue; /* skip different SSID*/ max_rssi = RTMPMaxRssi(pAd, pStaCfg->RssiSample.LastRssi[0], pStaCfg->RssiSample.LastRssi[1], pStaCfg->RssiSample.LastRssi[2]); if (pBss->Rssi < (max_rssi + RSSI_DELTA)) continue; /* skip AP without better RSSI*/
Миграция по схеме без 802.11r конечно не говорит о том, что в таких конфигурациях прощай бесшовность. Абсолютно нет. Но процедура аутентификации будет при каждой миграции будет осуществляться целиком (все 4ре стадии).
Плюс добавится критерий RSSI на кандидате > -50. Т.е. процедура миграции будет запущена заметно позже чем в случае с 802.11r.
А вызывается оно вот таким вот макаром:
#ifdef DOT11R_FT_SUPPORT if (pStaCfg->Dot11RCommInfo.bFtSupport && pStaCfg->Dot11RCommInfo.bInMobilityDomain) rv = FT_CheckForRoaming(pAd, wdev); #endif /* DOT11R_FT_SUPPORT */ /* Add auto seamless roaming*/ if (rv == FALSE) rv = MlmeCheckForFastRoaming(pAd, wdev);
Т.е. если включена поддержка FT и задан MD то дёргаем FT_CheckForRoaming. Если кандидат не найден пробуем дёрнуть MlmeCheckForFastRoaming.
Если FT отключено, то сразу зовём MlmeCheckForFastRoaming.
Следует обратить внимание на 4 момента:
1) в случае FT не сверяется SSID на текущей и кандидате, вместо этого всегда используется MobileDomain
2) без поддержки Over DS (что, из практики, почти всегда так) при миграции между ТД на разных каналах и тем более диапазонах никакого 802.11r не будет
3) режимы шифрования должны совпадать чётко на всех узлах ибо сравниваются в лоб
4) наличие R меняет не только процедуру миграции, но и критерии выбора кандидата, и как следствие целиком поведение клиента
Вот такой вот бубуль гум. Это всего лишь один частный пример реализации. У QCA и BCM там собственные навороты. Не помню у кого (у QCA по-моему) там целая бальная оценка в зависимости от возможностей ТД.
Надеюсь в будущем будет свободное время распишу с примерами кода. Но МТК при миграции “рассуждает” именно так ;)
Всем удачи в строительстве качественных решений.
P.S. К вопросу о пользе заглядывать в код клиента перед проектированием сети, жаль редко возможно. ;)
This post was last modified on 01/03/2023 11:26
Эта тема навеяна многочисленными инструкциями по настройке роутеров. И касается далеко не только Wive. Рекомендации…
Перед Новым Годом принято подводить итоги и принимать решения которые зададут вектор развития на год…
Пандемийный кризис начавшийся уже более 2х лет назад не перестаёт ставить всё более сложные задачи.…
Затишье? А вот и нет… Работа кипит, поставлены амбициозные цели. По планам до конца года…
Причиной для написания этой заметки стала очередная итерация обсуждения с потенциальными заказчиками функционала ПО. Когда…
На сегодняшний день все необходимые и запланированные, для уже выпускаемого оборудования, возможности реализованы и доведены…