(&self, args: &BluetoothLEAdvertisementReceivedEventArgs)
| 140 | } |
| 141 | |
| 142 | pub(crate) fn update_properties(&self, args: &BluetoothLEAdvertisementReceivedEventArgs) { |
| 143 | let advertisement = args.Advertisement().unwrap(); |
| 144 | |
| 145 | // Advertisements are cumulative: set/replace data only if it's set |
| 146 | if let Ok(name) = advertisement.LocalName() { |
| 147 | if !name.is_empty() { |
| 148 | let name_str = name.to_string(); |
| 149 | let mut adv_name_guard = self.shared.advertisement_name.write().unwrap(); |
| 150 | *adv_name_guard = Some(name_str.clone()); |
| 151 | drop(adv_name_guard); |
| 152 | // Also use as local_name fallback if we don't have one yet |
| 153 | let local_name_guard = self.shared.local_name.read().unwrap(); |
| 154 | if local_name_guard.is_none() { |
| 155 | drop(local_name_guard); |
| 156 | let mut local_name_guard = self.shared.local_name.write().unwrap(); |
| 157 | *local_name_guard = Some(name_str); |
| 158 | } |
| 159 | } |
| 160 | } |
| 161 | if let Ok(manufacturer_data) = advertisement.ManufacturerData() { |
| 162 | if manufacturer_data.Size().unwrap() > 0 { |
| 163 | let mut manufacturer_data_guard = |
| 164 | self.shared.latest_manufacturer_data.write().unwrap(); |
| 165 | *manufacturer_data_guard = manufacturer_data |
| 166 | .into_iter() |
| 167 | .map(|d| { |
| 168 | let manufacturer_id = d.CompanyId().unwrap(); |
| 169 | let data = utils::to_vec(&d.Data().unwrap()); |
| 170 | |
| 171 | (manufacturer_id, data) |
| 172 | }) |
| 173 | .collect(); |
| 174 | |
| 175 | // Emit event of newly received advertisement |
| 176 | self.emit_event(CentralEvent::ManufacturerDataAdvertisement { |
| 177 | id: self.shared.address.into(), |
| 178 | manufacturer_data: manufacturer_data_guard.clone(), |
| 179 | }); |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | // The Windows Runtime API (as of 19041) does not directly expose Service Data as a friendly API (like Manufacturer Data above) |
| 184 | // Instead they provide data sections for access to raw advertising data. That is processed here. |
| 185 | if let Ok(data_sections) = advertisement.DataSections() { |
| 186 | // See if we have any advertised service data before taking a lock to update... |
| 187 | let mut found_service_data = false; |
| 188 | for section in &data_sections { |
| 189 | match section.DataType().unwrap() { |
| 190 | advertisement_data_type::SERVICE_DATA_16_BIT_UUID |
| 191 | | advertisement_data_type::SERVICE_DATA_32_BIT_UUID |
| 192 | | advertisement_data_type::SERVICE_DATA_128_BIT_UUID => { |
| 193 | found_service_data = true; |
| 194 | break; |
| 195 | } |
| 196 | _ => {} |
| 197 | } |
| 198 | } |
| 199 | if found_service_data { |
no test coverage detected