Lees weergave

Apple Releases Firmware Update for 140W USB-C Power Adapter

Apple today released a firmware update (version 1.4.90) for its 140W USB-C Power Adapter.

It is unclear what is included in the latest firmware, as Apple does not publish release notes for this. The update will be installed automatically over time when the power adapter is plugged in and connected to a Mac or other device. There is no way to manually apply the update.
This article, "Apple Releases Firmware Update for 140W USB-C Power Adapter" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Apple Likely to Announce Beats 360 This Month

Apple today released a firmware update (4A203) for its upcoming Beats 360 headphones, suggesting that a launch is approaching. With the firmware now available, it seems likely that Apple will announce the Beats 360 at some point in September.


Beats 360 have already leaked across multiple regulatory databases and retail listings over the past several months, and soccer stars like Lamine Yamal and Antonee Robinson were spotted wearing them around the 2026 FIFA World Cup.

MacRumors was first to report on the Beats 360 name last month after the headphones appeared in various retail listings on Amazon and other reseller websites, some of which have since been removed. The listings revealed that the headphones will be available in Black, Cloud, Sky, and Pink, at a minimum. There will also be interchangeable Performance Knit and UltraPlush ear cushions and headbands that come in those same four colors, plus extra options like Volt and Navy, allowing you to create your own personalized look.

Beats 360 have a unique design with some similarities to the AirPods Max, including telescoping headband arms that smoothly extend and stay in place to maintain the desired fit. One of the product listings said the over-ear headphones offer up to 1.75× more noise cancellation than the Beats Studio Pro that came out in 2023.


The listing also said that the Beats 360 are Apple's first-ever sweat-resistant and water-resistant over-ear headphones, with an IPX4 rating.

Other features and specs mentioned in the listing included all-day battery life, a fold-flat design, and a high-fidelity acoustic platform. According to code uncovered by MacRumors contributor Aaron Perris, the Beats 360 will support hands-free Siri, meaning that you can say "Hey Siri" or simply "Siri" to activate the assistant.

Beats 360 will come with a set of interchangeable Performance Knit cushions and a woven ripstop fabric carrying case, but customers will need to supply their own USB-C charging cable and power adapter. One listing said the headphones will be priced at $299.99 in the U.S., but we cannot confirm if that information is accurate.

Beats Studio Pro are regularly priced at $349.99.

It is unclear exactly when Apple plans to officially unveil the Beats 360, but with all of these leaks across regulatory databases, athlete teasers, retail listings, and firmware updates, an announcement this month seems likely.
This article, "Apple Likely to Announce Beats 360 This Month" first appeared on MacRumors.com

Discuss this article in our forums

  •  

How to Watch Apple's 'Surprise and Shine' September 9 Event

Apple is hosting an online streaming event for the public and press on Wednesday, September 9 at 10:00 a.m. Pacific Time. The company is expected to announce new iPhone 18 Pro models and a new foldable iPhone alongside new Apple Watch models, and potentially AirPods 5 and other products during the event, dubbed "Sunshine and Shine." Here's how you can watch it and when, wherever you are in the world.


There are multiple ways to watch the September 9 event, with details listed below. We've also included a useful guide on when the event will take place in your particular time zone.

Apple Events Website


With the Apple Events website, you can watch the event live on a Mac, iPhone, ‌iPad‌, PC, or any other device with a web browser. The Apple Events website works in Safari, Chrome, Firefox, and other main browsers.


Just navigate to www.apple.com/apple-events/ using a web browser at the appropriate time to watch. You can visit the site now to add an event reminder to your calendar.

YouTube


Apple also plans to stream the event live on YouTube, which is perhaps the easiest and most efficient way to watch because the YouTube live stream can be viewed on every platform where YouTube is available, which is pretty much all platforms, from smartphones and tablets to consoles and smart TVs.


Apple has posted a placeholder for the September 9 event on YouTube, and you can visit it now to set an event reminder.

Apple TV App


Apple used to have a dedicated Apple Events app on the Apple TV, but ahead of WWDC 2020, it was folded into the Apple TV app. On event day, there will be a prominent ‌Apple TV‌ app section dedicated to the live stream, which can be watched on any device where the ‌Apple TV‌ app is available.


This includes the ‌Apple TV‌, iPhones, iPads, and Macs, as well as select smart TVs, streaming devices, and gaming consoles. If you have an ‌Apple TV‌, the ‌Apple TV‌ app is one of the best ways to watch the event live. Apple hasn't updated the ‌Apple TV‌ app with the new event as of yet, but it should be added soon.

When to Watch the Apple Event


Apple's event will take place at 10:00 a.m. Pacific Time, like most Apple events. Event times in other time zones are listed below.
  • Honolulu, Hawaii — 7:00 a.m. HST

  • Anchorage, Alaska — 9:00 a.m. AKDT

  • Cupertino, California — 10:00 a.m. PDT

  • Phoenix, Arizona — 10:00 a.m. MST

  • Vancouver, Canada — 10:00 a.m. PDT

  • Denver, Colorado — 11:00 a.m. MDT

  • Dallas, Texas — 12:00 noon CDT

  • New York, New York — 1:00 p.m. EDT

  • Toronto, Canada — 1:00 p.m. EDT

  • Halifax, Canada — 2:00 p.m. ADT

  • Rio de Janeiro, Brazil — 2:00 p.m. BRT

  • London, United Kingdom — 6:00 p.m. BST

  • Berlin, Germany — 7:00 p.m. CEST

  • Paris, France — 7:00 p.m. CEST

  • Cape Town, South Africa — 7:00 p.m. SAST

  • Helsinki, Finland — 8:00 p.m. EEST

  • Istanbul, Turkey — 8:00 p.m. TRT

  • Dubai, United Arab Emirates — 9:00 p.m. GST

  • Delhi, India — 10:30 p.m. IST

  • Jakarta, Indonesia — 12:00 a.m. WIB next day

  • Shanghai, China — 1:00 a.m. CST next day

  • Singapore — 1:00 a.m. SGT next day

  • Perth, Australia — 1:00 a.m. AWST next day

  • Hong Kong — 1:00 a.m. HKT next day

  • Seoul, South Korea — 2:00 a.m. KST next day

  • Tokyo, Japan — 2:00 a.m. JST next day

  • Adelaide, Australia — 2:30 a.m. ACST next day

  • Sydney, Australia — 3:00 a.m. AEST next day

  • Auckland, New Zealand — 5:00 a.m. NZST next day

MacRumors Coverage


If you're not able to watch or just want to follow along with us as we watch the event unfold, visit MacRumors.com for our liveblog or follow us on Twitter at MacRumorsLive for our live tweet coverage.

Both the MacRumors site and our X (Twitter) account are excellent ways to discuss the new announcements with other Apple enthusiasts as Apple unveils its new products. Later in the day and throughout the week, we'll also have much more in-depth coverage of all of Apple's announcements, so make sure to stay tuned.
This article, "How to Watch Apple's 'Surprise and Shine' September 9 Event" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Motion, Colour, Captions, Kit – These Weeks in Firefox: Issue 207

Highlights

Friends of the Firefox team

Resolved bugs (excluding employees)

Script to find new contributors from bug list

Volunteers that fixed more than one bug

  • :Vincent
  • japandi
  • Nirmal Advani
  • Sebastian Zartner [:sebo]
  • tanvi.manku

New contributors (🌟 = first patch)

Project Updates

Add-ons / Web Extensions

Addon Manager & about:addons
  • As part of Nova about:addons work:
    • Introduced a shared localization module for built-in and curated AMO-hosted theme names, and updated the corresponding about:addons theme test to expect the new “Default” theme name shown when Nova is enabled – Bug 2055936 / Bug 2058235
    • Added a message bar to the about:addons themes picker to surface AMO-hosted Nova theme download and install failures instead of failing silently – Bug 2054548
WebExtensions Framework
  • Fixed a startup race where an extension’s restored dynamic content scripts could be missing from the parent WebExtensionPolicy due to stale shared data – Bug 2058719
WebExtension APIs
  • Fixed publicSuffix.isKnownSuffix() to reject invalid domain-name characters, including wildcard suffixes, that could previously be matched as a known public suffix – Bug 2059819
  • Fixed the frameId reported by webRequest events for requests made from workers, including importScripts()-loaded scripts, which were previously attributed to the wrong frame – Bug 2048884
    • Thanks to Giulio B for the fix to webRequest frameId attribution for worker requests.

DevTools

WebDriver

Fluent

Lint, Docs and Workflow

New Tab Page

Performance Tools (aka Firefox Profiler)

Search and Urlbar

  •  

Apple Releases iOS 26.6.2

Apple today released iOS 26.6.2 with a fix for "an issue that prevents downloading a software update over a cellular connection."


The minor software update is rolling out now for the iPhone 11 series and newer. To update your iPhone, open the Settings app and tap on General → Software Update. It might take a few minutes for the update to be visible to everyone.

iOS 26.6.2 arrives approximately three weeks after iOS 26.6.1, which delivered security fixes.

Apple is expected to release iOS 27 later this month, with the company likely to announce a release date during its event this Wednesday.

iPadOS 26.6.2 is also out with the same fix.
Related Roundups: iOS 26, iPadOS 26
Related Forum: iOS 26

This article, "Apple Releases iOS 26.6.2" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Apple Event Tomorrow: iPhone 18 Pro and iPhone Ultra Cheat Sheet

Apple's biggest event of the year is almost here, and all eyes are on Cupertino. With the first foldable iPhone expected to headline Apple's "Surprise and Shine" event on Wednesday, September 9, at 10:00 a.m. Pacific Time, the rumor mill has been running full throttle, fuelled by the biggest single design change in the life of the iPhone.


To get you up to speed, here's a quick reference guide to the rumoured upgrades, expected prices, and possible pre-order/release dates of everything we're expecting to see tomorrow.

Rumors by Model


iPhone 18 Pro / Pro Max



  • Similar overall design to the iPhone 17 Pro models, with a more uniform finish across the aluminum and glass back.

  • Smaller Dynamic Island, said to be achieved by Apple moving some Face ID components beneath the screen.

  • More efficient LTPO+ displays.

  • A20 Pro chip manufactured using TSMC's 2nm process.

  • 12GB of RAM and 256GB starting storage.

  • Variable-aperture main camera for greater control over light and background blur – although reports disagree on whether this will be exclusive to the Pro Max.

  • Possible Samsung image sensor for improved image quality and camera responsiveness.

  • Simplified Camera Control button that retains pressure sensing but removes the capacitive layer.

  • Larger battery in the Pro Max, which could well result in a slightly thicker and heavier body.

  • Possible Apple C2 modem, although U.S. models could retain Qualcomm modems for mmWave support.

  • The strongest color rumors include Dark Cherry, Light Blue, and Silver. Other rumors have suggested no Silver, and a black finish has also been suggested.


iPhone Ultra (Foldable)



  • Apple's first folding iPhone, with "iPhone Ultra" among the rumored names, with "iPhone Fold" and "iPhone Duo" remaining outlying possibilities.

  • Book-style design with an approximately 5.5-inch outer display and 7.8-inch inner display.

  • Chassis measuring just 4.5mm thick when unfolded.

  • Liquid-metal hinge and an extremely inconspicuous – but not completely invisible – display crease.

  • Touch ID integrated into the Side button in lieu of Face ID.

  • Wide and Ultra Wide rear cameras, plus selfie cameras on both the outer and inner displays.

  • A20 Pro chip and an expected 12GB of RAM.

  • MagSafe charging support.

  • iPad-like multitasking, including side-by-side apps.

  • Silver/white and a very dark indigo finish among the rumored colors.


Apple Watch Series 12



  • Familiar design, with no major change to the case expected.

  • Faster S12 chip and improvements to health and fitness tracking.

  • Possible return of a ceramic case, with white and dark gray versions reportedly tested.

  • Continuous heart-rate monitoring throughout the day among the features Apple is testing, along with a new "Readiness" app.

  • More wellness metrics through revamped Health and Fitness experiences.


Apple Watch Ultra 4



  • Similar design to the Apple Watch Ultra 3.

  • Faster S12 chip and related health and fitness improvements.

  • Likely continuous heart-rate collection if the Series 12 gets it.

  • Possible expansion of satellite capabilities, including Apple Maps and photo sharing in Messages.


AirPods 5 (Possible)



  • Two versions expected, with and without active noise cancellation.

  • Possible H3 chip for better sound quality and lower latency.


iPhone 18 (Regular)


The regular iPhone 18 is not expected to feature tomorrow. Apple is reportedly moving that model's launch to spring 2027, when the iPhone 18e and iPhone Air 2 are also expected to debut as part of a new split-year release schedule.

iPhone 18 Pro and iPhone Ultra Pricing Expectations


Higher memory costs could push up prices for both Pro models this year. Based on TrendForce's forecasts for the Pro models and Bloomberg's latest reporting on the foldable, the possible U.S. starting prices are:

















Model Estimated Starting Price
iPhone 18 Pro $1,249–$1,299
iPhone 18 Pro Max $1,349–$1,399
iPhone Ultra $2,199 (rumored)


Remember that these are estimates, with the Pro figures representing possible prices sourced from TrendForce's projected increases. That said, Bloomberg's Mark Gurman today also reported that Apple has discussed a $2,199 starting price for the foldable, with some upgraded storage configurations potentially approaching $3,000. Reliable figures for every storage tier are not available.

When Can I Pre-order iPhone 18 Pro and iPhone Ultra?


iPhone 18 Pro pre-orders could begin on Saturday, September 12, at midnight Pacific Time / 3 a.m. Eastern Time. The potential Saturday opening would avoid September 11, similar to Apple's approach in 2015.

The foldable's schedule is less certain, with some reports of manufacturing challenges potentially delaying a release until the fourth quarter of 2026. However, Gurman has said he would be "very surprised" if the foldable iPhone does not come out at the same time as the iPhone 18 Pro models or "very close" to them.

When Do iPhone 18 Pro and iPhone Ultra Launch?


Friday, September 18 is the most likely release date for the iPhone 18 Pro and Pro Max. It's our best educated guess, but we believe that is when deliveries and retail availability will begin.

As already mentioned, reports remain divided on the foldable's launch schedule. There's still a possibility that its unveiling tomorrow may precede its arrival in stores by several weeks or more.

MacRumors Coverage


Follow MacRumors.com and our MacRumorsLive account on Twitter (X) for coverage as the announcements happen. We'll have individual stories on the new products, followed by more detailed looks at their features, pricing, and availability throughout the week. Stay tuned!
Related Forum: Apple Watch

This article, "Apple Event Tomorrow: iPhone 18 Pro and iPhone Ultra Cheat Sheet" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Next Apple TV's Chip Revealed in Latest Leak

The next Apple TV 4K will be equipped with an A19 or A19 Pro chip, according to evidence in Apple's code uncovered by MacRumors contributor Aaron Perris. In particular, the device's model identifier points towards the A19 generation of chips.

Accordingly, the next Apple TV would have 8GB or 12GB of RAM, up from 4GB in the current 2022 model with the A15 Bionic chip. Other rumored upgrades for the next model include Siri AI support, an Apple-designed N1 wireless networking chip with Wi-Fi 7 support, and a revised Siri Remote.
Related Roundup: Apple TV
Buyer's Guide: Apple TV (Don't Buy)

This article, "Next Apple TV's Chip Revealed in Latest Leak" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Announcing new builds for 8 September 2026

Hello Windows Insiders, Today, we’re releasing new Windows 11 Insider Preview builds to the Beta and Experimental channels. New builds this week Select your channel below to view its release notes: For those on other specific Windows build versions, here are today’s new builds and release notes:

Notable new features:

[Cross-device resume improvements]

Release channel: Experimental We're making it easier to continue where you left off on your PC. When you resume a webpage from your phone and the phone's browser isn't installed on your PC, the Resume hovercard now gives you two options: open the page directly in your PC's default browser or install the phone's browser for a native experience. This update helps you continue your work immediately without requiring an app installation first. [caption id="attachment_179156" align="aligncenter" width="864"]The Resume hovercard provides an option to open the webpage in the PC's default browser. The Resume hovercard provides an option to open the webpage in the PC's default browser.[/caption] [caption id="attachment_179157" align="aligncenter" width="684"]The Resume hovercard provides an option to install the originating phone browser. The Resume hovercard provides an option to install the originating phone browser.[/caption]

[Narrator]

Release channel: Experimental Read and explore math equations with Narrator We are adding math reading and navigation support in Narrator, bringing clearer and more natural math experiences to users who are blind or have low vision. Math is at the heart of STEM education and learning, and this update helps students and professionals independently read, understand, and explore equations, formulas, and scientific notations with confidence. Read more in release notes link above. [caption id="attachment_179158" align="aligncenter" width="2303"]Screenshot of Windows settings page with Narrator Math reading settings page open Screenshot of Windows settings page with Narrator Math reading settings page open[/caption]

[Magnifier]

Release channel: Experimental Magnifier now understands each of your displays
  • Every screen keeps its own view, at its own zoom. In earlier versions of Magnifier, zooming in stretched a single magnified view across all of your displays, so one screen's zoom followed you everywhere and screen edges blurred together. With this update, each monitor's boundary is respected, and each monitor can hold its own zoom percentage. Your writing screen can sit at 300% while your reference screen stays at 150%, and the magnified view no longer spills from one display into the next. This matters because different tasks, and different screen resolutions, often call for different levels of magnification to stay comfortable to read. Read more in release notes link above.
[caption id="attachment_179159" align="aligncenter" width="758"]UI showing Magnifier settings with Zoom per display enabled, allowing each monitor to maintain its own zoom level. UI showing Magnifier settings with Zoom per display enabled, allowing each monitor to maintain its own zoom level.[/caption] [caption id="attachment_179160" align="aligncenter" width="1041"]UI showing Magnifier's multiple display controls, including independent zoom and view locking options. UI showing Magnifier's multiple display controls, including independent zoom and view locking options.[/caption] Thanks, Stephen and the Windows Insider Program team
  •  

Apple Watch SE 3 is Suddenly Unavailable

Nearly all configurations of the Apple Watch SE 3 are suddenly "unavailable" on Apple's online store in the U.S. and other countries we checked, for reasons unknown.


Apple is holding an event this Wednesday to announce new iPhones and Apple Watches, but an Apple Watch SE 4 was not expected tomorrow, as new generations of the Apple Watch SE have never been released in back-to-back years. The original Apple Watch SE debuted in September 2020, the Apple Watch SE 2 arrived in September 2022, and the Apple Watch SE 3 was announced in September 2025.

Is this a sign that an Apple Watch SE 4 will be announced tomorrow after all, or is this simply a temporary issue that will be resolved soon? We shall see.

Thanks, Logan!
Related Roundup: Apple Watch SE 3
Related Forum: Apple Watch

This article, "Apple Watch SE 3 is Suddenly Unavailable" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Listening to families. Improving Microsoft Family.

The latest Windows Family Safety improvements are part of a broader effort to create safer, age-appropriate digital experiences for kids and families. As we’ve recently outlined, Microsoft Family has been on a focused journey to raise the quality of the everyday offering that parents and kids rely on — and that journey started by listening to you. We gathered feedback from families and let it guide our priorities, month after month.   The result is a steady stream of meaningful fixes we continue to iterate on:  
  • Parental approvals for offerings like screen-time extensions, app access, and purchases now happen faster, so kids aren’t left waiting and parents stay in control.
  • We restored clear visibility into web and app activity so parents can trust what they see in their reports.
  • Made spending more transparent, with wallet balances.
  • We also gave adults in a family more control over their own experience, making it far easier to add, manage, or leave a family group 
We know these areas have presented pain points, and while we've made progress, we know some of you may still run into issues. We're continuing to improve and will continue to listen to your feedback as we improve the experience.  

Parental control: Faster and reliable approval flows 

Parents and children may have experienced inconsistent and noticeable delays while approving children requests such as app access, screen time extensions, and purchase approvals. During these delays, children are unable to access the requested content or continue their activities, while parents are left uncertain whether their approval has been received and applied.  Parental approvals for app access, screen time extensions, and purchases now happen faster than before, reducing wait times and frustration for parents and kids alike.  

Activity reporting: full app coverage 

Some parents noticed that certain apps were missing from activity reports, making it difficult to fully understand how their child was using their device. Activity reporting now includes broader app coverage across all applications used on a child's PC, providing a more complete and trustworthy view. Additional improvements to usage time accuracy are also on the way.  Both parent and children will have the broader view of apps used and time spend.  

Family funding balance after top-up 

Family funding balance was not reflecting proper updated balance but now this issue has been addressed, and parents can now easily manage the funds for their children.   Family Safety Spending Each of these improvements came from a real family experience — from issues parents told us mattered most: speed, accuracy, control, transparency, and peace of mind.  This is the compounding effect of a team that treats every piece of customer feedback as a commitment to do better. Thank you to every parent who shared their voice; you’ve shaped this product, and we’re just getting started.  All of the above fixes are available in the latest versions of the Family Safety mobile app both iOS and Android are available. You can also access Family Safety on the web by visiting: https://account.microsoft.com/family/  

What’s next 

We also know the journey is not over. While we have made important progress, some families may still run into issues, and we want to hear about them.  If something is not working the way you expect, please reach out to us at familysafetyfeedback@microsoft.com. That inbox is more than a contact point — it is an open invitation from our team to yours. Your feedback helps us understand what families are facing today so we can fix issues at the earliest and keep improving.  Thank you to every parent who shared their voice. You have shaped this product, and you will continue to shape what comes next.  We have been listening. We have been fixing. And we will keep going.
  •  

Helping families and educators support safer experiences and healthier habits on Windows

Our children and teens are growing up in a digital world where apps, games, and AI-powered tools are part of how they learn, play, create, and connect. For parents and educators, that brings both opportunity and responsibility: digital experiences should help young people explore with confidence while supporting their wellbeing, building healthy habits, respecting their privacy, and providing protections that are appropriate for their age.  At Microsoft, we believe safety should be easier for families to understand and easier for developers to build into experiences for children to use. On Windows, that starts with the account. Microsoft account is a trusted foundation through which Windows brings age-appropriate protections and parental choices into more of the digital experiences encountered by children and teens every day. A child’s account should help unlock safer, more age-appropriate experiences wherever they use Windows. This is the first in a series of posts on family safety on Windows. Over the coming months I’ll share what we're building — in the account, in the platform, and in the tools we provide to parents, educators, and developers. As Pavan recently shared, Family is a key focus area in our commitment to improving Windows quality. We'll build in the open: shipping new capabilities, listening closely to what families tell us, and refining as we learn. 

From account to safer experiences 

Every experience on Windows starts with identity, and for consumers, that foundation is the Microsoft account (MSA).  MSA enables Windows to understand key context about the user in a consistent and privacy-conscious way: 
  • Whether the user is a child, teen, or adult 
  • Whether parental controls or consent apply 
  • Whether age verification has been completed 
This creates a simple, scalable model:  User account → age signal → age-appropriate experience and controls  Because this foundation is tied to the account, protections are designed to follow the user across Windows and apps, creating safer experiences consistently, not just in individual features. This enables product experiences to support a user’s stage of life. Protections are matched to children, teens, and adults. 

Extending safety across the ecosystem with the Windows Age APIs 

As experiences expand across apps, services, and AI, one challenge becomes clear: how can these experiences consistently understand and respect a user’s age?  To address this, Windows is introducing a new platform capability: the Windows Age API.  This API brings age awareness beyond the operating system by making it available across the entire Windows ecosystem so that apps and services can deliver age-appropriate experiences using the same trusted foundation. By making age awareness available as a platform capability, Windows helps developers build safeguards into experiences from the start rather than placing the burden on children and families to manage protections app by app.  The Windows Age API offers the following capabilities: 
  • GetUserAgeRangeAsync: Provides non-personally identifiable age group categories for apps to utilize in providing safe and age-appropriate user experiences, while protecting the date of birth data and overall privacy of users. Age groupings available via the API include- under 10, 10-12, 13-15, 16-17, 18+.
  • GetAgeVerificationStatusAsync: Provides verified age status for scenarios when self-reported age is not sufficient.
  • CheckAgeStatusAsync: Extends the functionality of the legacy CheckUserAgeConsentGroupAsync API to offer child, minor, or adult classification globally and as defined by regional policies.
These signals are designed to protect privacy: 
  • Apps receive only the age-related signal needed for the experience and not sensitive personal data such as full date of birth
  • Users remain in control through consent and platform-level controls
  • Age information is handled consistently at the platform level to reduce unnecessary sharing and fragmentation 
This enables a new level of consistency across Windows experiences. Apps can recognize when a user is under a certain age and adjust features accordingly, helping create safer, more appropriate interactions without requiring manual setup. This platform approach also helps make protections more consistent and accessible, so safer experiences do not depend on whether a family discovers or configures controls in each individual app.  Just as importantly, this extends to emerging experiences, including AI, where applying age-appropriate safeguards is increasingly important as innovation continues to evolve.  By making this a platform capability, Windows drives safety which is built-in and available across apps, services, and new scenarios.   For more details, including developer guidance, check out the Windows Age API documentation found at https://aka.ms/windows-age-api. 

Building toward high-confidence age assurance 

In many cases, understanding age is not enough. Increasingly, certain experiences require high confidence that a user is an adult.  To support this, Microsoft is expanding age assurance through the Microsoft account using Microsoft Age Verification (MAV), a centralized platform that enables users to verify their age once and use that status across Microsoft experiences. Developers can access this verified status through Windows Age APIs.   Age verification is already available in Microsoft Storefronts in Singapore, Brazil, and Australia. As more regions around the world expand regulatory requirements for age verification, Microsoft will add support for those geographies and product scenarios.  MAV creates a simple, consistent model:  Verify once → use everywhere  Verified status is stored with the Microsoft account and can be used across Windows and apps to enable appropriate experiences, helping reduce friction while improving safety.  

Making safety clearer from the start 

We’re also improving how parental controls are surfaced during device setup, so families can more easily understand available protections and make informed choices from the very beginning.  In regions such as France and others, Windows is raising the visibility of parental controls and consent experiences during setup, designed to increase awareness of the available offerings and enabling early application by parents.   Image of Family Safety built into Windows

Family Safety and Parental Controls 

With Family Safety built into Windows, parents can set up a child's device and manage screen time, apps, and content in one place. Over the past six months, we’ve focused on making those everyday moments more dependable – faster parental approvals, clearer activity reporting, and more overall control – guided by what parents told us mattered most. You can read more about what’s improved and what’s coming next here: Listening to families. Improving Microsoft Family. 

Raising the bar for digital safety 

Digital safety must be built into the platform—not added on later.  With Microsoft account as the foundation, and with investments like the Windows Age API expanded age assurance, and available parental controls, Windows is working to support a safer digital environment that is also age-appropriate, privacy-conscious, and easier for families to navigate.  Our goal is to help create experiences where safety, privacy, and participation can work together across the Windows ecosystem. 

Availability 

The Windows Age APIs are broadly available to Windows Insiders now and will be available to all Windows users soon. The CheckAgeStatusAsync API will be available with a future update.
  •  

AirPods Turn 10

Apple unveiled the first AirPods on September 7, 2016, meaning the iconic wireless headphones are now 10 years old. However, the AirPods did not launch until December that year.

On the same day, Apple ignited controversy when it introduced the iPhone 7 and iPhone 7 Plus without a headphone jack. Apple still sells EarPods for customers who want wired headphones, with 3.5mm headphone jack, Lightning, and USB-C versions available for use with a wide variety of devices.
Related Roundup: AirPods 4
Buyer's Guide: AirPods (Caution)
Related Forum: AirPods

This article, "AirPods Turn 10" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Faster reviews and quality recognition for Microsoft Edge extensions

Building an extension has never been easier. Rapid adoption of AI-assisted coding is enabling developers to build extensions faster than ever. We have seen that momentum on the Edge Add-ons site. More developers are building, iterating, and submitting extensions, which is great for the ecosystem and ultimately gives users more choice. It also creates a challenge: how do we keep up with the pace at which the ecosystem is growing, while maintaining a high bar for quality?

Speeding up extension reviews

We know time matters to developers. Whether launching an extension, fixing an issue, or making improvements, waiting for a review can slow progress. Last year, we introduced an expedited review process for high-quality and high-value extensions. Since then, submission volumes have continued to increase, and our review pipeline has experienced additional strain, causing an increase in extension review turnaround time. At the same time, at Edge we have always held a very high bar on quality. So, the challenge in front of us was to reduce the turnaround time for extension updates while ensuring the quality of extensions is maintained. To address this challenge, we've introduced automation for many of the repeatable validation checks that are part of the review process and streamlined how reviews move through our pipeline. This doesn't change our review standards or reduce the checks an extension must pass. Instead, it helps us identify known policy violations and security issues more consistently while allowing reviewers to spend more time on complex cases that benefit from human judgment. The result is a more efficient review process that helps extensions move through the pipeline faster while maintaining the high quality and security standards developers and users expect from the Edge Add-ons site. For developers, this mean bug fixes and new features reach your users sooner. Our objective is to make Edge the easiest place to build, publish, and grow an extension. Faster reviews are just one part of that investment. We continue to look for ways to reduce friction across the developer journey while maintaining a trusted marketplace for users.

Recognizing quality as it improves

As more extensions become available on the Edge Add-ons site, helping users discover extensions they can trust is equally important. The Featured badge has long helped users identify high-quality extensions in the Edge Add-ons site. It serves as a trust signal, highlighting extensions that demonstrate a strong commitment to quality, reliability, security, and user experience. Featured badge The Featured badge is awarded to select extensions that align with Best practices for extensions. Our evaluation considers more than 60 quality signals across multiple dimensions of an extension. Today, much of our evaluation process is automated to make it more consistent, objective, and scalable as the ecosystem expands. But quality is not static. As we continue to refine our badging criteria, and as developers continuously improve their extensions by fixing issues, refining experiences, and responding to user feedback, we automatically update badges on the Edge Add-ons site. And now, to more quickly recognize quality improvements, we're refreshing Featured badges every 15 days. With this more frequent cadence, high-quality extensions can earn recognition sooner, and developers receive faster feedback on their investments in quality. At the same time, users benefit from a more up-to-date view of the extensions that meet our quality standards. Our goal is simple: make it easier for users to find extensions they can trust while ensuring developers who invest in quality are recognized more quickly.
  •  

Apple to Introduce All-New 'Readiness' App Tomorrow

Apple plans to announce an all-new "Readiness" app during its "Surprise and Shine" event this Wednesday, according to Bloomberg's Mark Gurman.


In a social media post today, Gurman said the "Readiness" app will be a "variant" of the existing Vitals app on the Apple Watch. "The idea is to better compete with software from Whoop and Oura," he said. For example, Oura's smart rings offer a daily "Readiness Score" from 0 to 100 that shows how prepared your body is for the day.

Introduced on watchOS 11, the Vitals app consolidates your key health metrics, including your average heart rate, respiratory rate, blood oxygen, wrist temperature, and sleep duration from the previous night. Based on many of the same metrics, the Readiness app would likely show you how recovered your body is for activity.


Evidence of the "Readiness" app in watchOS 27 beta code was already discovered a few days ago by a MacRumors forum member known as "pdfu."

The app will be unveiled alongside the Apple Watch Series 12 and Apple Watch Ultra 4. Gurman previously reported that both of these new models will feature continuous heart rate sensing, regardless of whether you are actively exercising.
This article, "Apple to Introduce All-New 'Readiness' App Tomorrow" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Dirk Eddelbuettel: RcppArmadillo 15.6.0-1 on CRAN: New Upstream Minor

armadillo image

Armadillo is a powerful and expressive C++ template library for linear algebra and scientific computing. It aims towards a good balance between speed and ease of use, has a syntax deliberately close to Matlab, and is useful for algorithm development directly in C++, or quick conversion of research code into production environments. RcppArmadillo integrates this library with the R environment and language–and is widely used by (currently) 1331 other packages on CRAN, downloaded 48.5 million times (per the partial logs from the cloud mirrors of CRAN), and the CSDA paper (preprint / vignette) by Conrad and myself has been cited 727 times according to Google Scholar.

This versions updates to the 15.6.0 upstream Armadillo release made yesterday. It extends solver options for poorly conditioned systems, and brings some updates and extension to the cube data type. For this release, we once again ran the usual complete reverse-dependency check which came back spotless, and did CRAN so no email exchange needed despite nearly 1300 reverse dependencies (but it ended up taking more than a single business day). Still, automation can be helpful when used with a well-maintained software stack. The package has also already been updated for Debian, built for r2u and r-universe, and will build shortly at CRAN for the different binary releases.

All changes since the last CRAN release follow.

Changes in RcppArmadillo version 15.6.0-1 (2026-09-07)

  • Upgraded to Armadillo release 15.6.0 (Medium Roast Cortado)

    • Expanded solve() with solve_opts::scale_thresh option to widen detection of poorly conditioned systems

    • Expanded trans() and .t() to handle cubes

    • Added permute() to rearrange dimensions of cubes (generalised transpose)

    • Added cubemul() for batched matrix multiplication of cube slices

Courtesy of my CRANberries, there is a diffstat report relative to previous release. More detailed information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the Rcpp R-Forge page.

This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can sponsor me at GitHub.

  •  

'Small Prophets' Renewed for Season 2 Following Apple TV Deal

Breakout hit comedy show "Small Prophets" has been renewed for a second season, according to Deadline, a little over a week after Apple TV acquired the worldwide rights to the show's first season. This was the first time the company has acquired the streaming rights to an existing show.

"Small Prophets" is set to stream on ‌Apple TV‌ worldwide starting on October 7, with creator Mackenzie Crook returning to write and direct season two.
Related Roundup: Apple TV
Buyer's Guide: Apple TV (Don't Buy)

This article, "'Small Prophets' Renewed for Season 2 Following Apple TV Deal" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Apple Sued Over Alleged Face ID Patent Infringement

TrinamiX, a subsidiary of the German chemical giant BASF, is suing Apple in the U.S. District Court for the Western District of Texas, accusing the company of infringing seven patents related to face authentication technology used in Face ID.


In its complaint, first reported by Reuters, trinamiX said it spent years developing technology to stop people from fooling face unlock systems with a photo, a fake mask, or a silicone copy of someone's face.

The complaint says Apple's original version of ‌Face ID‌, introduced with the iPhone X in 2017, did not use trinamiX's technology, but that newer iPhones and iPads do. TrinamiX's system is designed to tell real skin apart from things like photos or masks, essentially adding a check that catches fakes conventional optical face scanning methods would miss.

The complaint alleges that "Apple knew or should have known of the high probability that updating its iPhones and iPads to incorporate ‌Face ID‌ using material and skin detection" infringed seven trinamiX patents, causing "substantial damages and irreparable injury." The seven patents cover two areas: detecting skin during face unlock and identifying what material something is made of.

TrinamiX names a broad swath of Apple devices as accused products, including the iPhone 15, iPhone 15 Plus, iPhone 15 Pro, iPhone 15 Pro Max, iPhone 16, iPhone 16e, ‌iPhone 16‌ Plus, ‌iPhone 16‌ Pro, ‌iPhone 16‌ Pro Max, iPhone 17, iPhone 17e, iPhone 17 Pro, ‌iPhone 17 Pro‌ Max, iPhone Air, 11-inch iPad Pro (4th generation), 12.9-inch ‌iPad Pro‌ (6th generation), and the 11- and 13-inch ‌iPad Pro‌ models with the M4 and M5 chips.

TrinamiX is asking the court to find that Apple infringed its patents, to block Apple from making, using, selling, offering for sale, or importing the accused products, and to award damages and attorneys' fees. The company has requested a jury trial. The full complaint is available via IP Fray.
This article, "Apple Sued Over Alleged Face ID Patent Infringement" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Apple Arcade Adds 'Pusheen's Place' and Four More Games in October

Apple today announced a new series of games coming to Apple Arcade in October, headlined by "Pusheen's Place."



The new games heading to ‌Apple Arcade‌ next month are as follows:


  • Pusheen's Place: The first officially licensed game starring Pusheen the Cat, letting players build a cozy paradise and collect more than 100 kitties while playing, crafting, and decorating rooms for characters like Pusheenicorn and Pancake Pusheen, alongside mini games such as Snack Stack, Parfait Pop, and Batch Match.

  • River City Survivors: An explosive survivors-like action game from the long running River City series, throwing players into waves of zombies with more than 20 playable characters, including franchise mainstays Kunio and Riki, and support for up to two companions.

  • Terraria+: A sandbox action adventure game where players fight, explore, and build through an ever expanding world, including the "Bigger & Boulder" 1.4.5 update, which adds a "Dead Cells" crossover and Pals from "Palworld," with support for up to seven players via Game Center or local Wi-Fi.

  • Touchgrind BMX 2+: A physics-based BMX stunt game with two finger controls designed to make every trick feel real.

  • 4 Pics 1 Word+: The Arcade edition of the puzzle game that has stumped and delighted more than 400 million players worldwide.



All of the new games will be available on October 1, 2026. Pusheen's Place joins Arcade's existing lineup of "cozy" titles, including "Hello Kitty Island Adventure," "Tamagotchi Adventure Kingdom," and "Cozy Caravan."

‌Apple Arcade‌ is a subscription service that provides access to more than 200 games across the iPhone, iPad, Mac, Apple TV, and Apple Vision Pro, all free of ads and in-app purchases. In the U.S., ‌Apple Arcade‌ costs $6.99 per month with a one-month free trial, and customers who purchase a new iPhone, ‌iPad‌, Mac, or ‌Apple TV‌ get three months of the service for free. ‌Apple Arcade‌ is also included in Apple One's Individual ($21.95), Family ($27.95), and Premier ($39.95) plans in the U.S., each with a one-month free trial. ‌Apple Arcade‌ can be accessed through the App Store and the Apple Games app.
This article, "Apple Arcade Adds 'Pusheen's Place' and Four More Games in October" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Apple Acquires Startup Working on 'Breakthrough Sensing Technology'

Earlier this year, Apple acquired California-based startup Sonera, according to a notice published today on the European Commission's website.


Sonera previously announced that it had developed "breakthrough sensing technology" that "non-invasively measures magnetic fields" generated by the brain and body. The company said its technology can analyze neural data without direct skin contact, giving it an advantage over traditional electrical sensing techniques.

"This proprietary technology holds the key to making brain activity as easy to measure as heart rate, temperature, and other physiological signals," said Sonera, in a 2023 press release. The company said its technology was "poised to enable an entirely new class of consumer wearables and experiences based on muscle activity."

Sonera said it had developed a biomagnetic chip that would enable use cases such as "advanced prosthetics control, continuous monitoring of neuromuscular conditions, discovery of disease biomarkers, and sport performance tracking," so this acquisition could pave the way for future Apple Watch health and accessibility features.
This article, "Apple Acquires Startup Working on 'Breakthrough Sensing Technology'" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Paul Tagliamonte: IP over Avian Carriers (Part 12/12) 🕊️

🕊️ This post is part of a series called "Pigeon". If this is the first post you've found, it'd be worth reading the intro post first and then looking over all posts in the series.

The final step to all of this was to tie together all my PHY RF code, Link layer parsers, and my background with operating systems to make this all feel like a normal thing my computer should be doing.

At the end of the day, I want my host system to know how to talk with a pigeon daemon, so I don’t have to reimplement basically everything else. My ability to use normal tools like curl or ping6 is pretty important here, so I need to reach for my old friend, the TUN interface. The TAP/TUN interface allows the kernel to route ethernet frames (TAP) or ip packets (TUN) to a userspace program responsible for handling delivery and reception – avoiding the need for a kernelspace driver for something that can be handled in userland.

🔒 wondering if doing this violates FCC Part 97 rules? I wrote up notes on my test setup for exactly this question, but the short answer is "no"!

I’m no stranger to playing with TAP/TUN, so this was pretty easy to snap together – although this time I avoided the whole ethernet proxying thing (to side-step lossy translations, maintaining two sets of mac address tables, and handle proxying NDP/ARP messages) – it was kinda a bad idea last time – so I just used TUN and straight IP for now. While implementing this, I decided I’d make a key assertion about all pigeon networks – namely, all pigeon IPv6 networks are a /64 in size, no more, no less. The reason why I’m doing this here is that, since pigeond does still does need a MAC address for the pigeon layer 2 protocol, we can write our daemon to always use SLAAC to set the TUN IP address without any new information.

Which leads us to a bit of an aside, but I have a point, I swear. A few years ago, my recreational RF adventures have lead me down a path where I decided to engage with ARIN to solve (once and for all) the massive headache I was running into with IPv6 numbering (really: always renumbering) my multi-site radio processing networks. It’s a lot of work to keep running correctly, but it’s solved a huge amount of problems for me.

The only “internal” thing we really need to outline for this post is that, at the highest level, my network (paultag.net) is split into an IP plan that looks roughly like:

Prefix Description
/44my full allocation of IP space
/4815 "regions"
/5464 "sites" per region. A "site" is assigned to a physical or logical location.
/641024 subnets per site. A subnet used by directly attached devices.

For this exercise, I used IP space from paultag.net’s experimental region (“region 8”), named side.band (2602:810:6008::/48) to connect my RF lab (“site 1” - 2602:810:6008:400::/54), and my two pigeon-specific subnets, “subnet 0” (2602:810:6008:400::/64) and “subnet 1” (2602:810:6008:401::/64) to my wider network. The first subnet (“subnet 0”) is a simple ethernet network to enable my RF-only nodes to communicate with the side.band gateway. The second subnet (“subnet 1”) is an RF-only pigeon network local to my lab.

back to radios

With all that set up, I assigned my first two nodes their MAC addresses, and set up the local RF only network segment. The nodes I brought online were the following:

Callsign IP
K3XEC/MN2602:810:6008:401:8e1f:64ff:fe35:4001
K3XEC/TH2602:810:6008:401:8e1f:64ff:fe35:4002

testing the pigeon network

And with that, I could begin to test that the host operating systems and RF links could properly exchange data locally from SDR to SDR. We can use ping6 to see if a plain-ole ICMPv6 ping round trips between hosts correctly:

$ ping6 2602:810:6008:401:8e1f:64ff:fe35:4001
PING 2602:810:6008:401:8e1f:64ff:fe35:4001 (2602:810:6008:401:8e1f:64ff:fe35:4001) 56 data bytes
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=1 ttl=64 time=426 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=2 ttl=64 time=397 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=3 ttl=64 time=419 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=4 ttl=64 time=418 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=5 ttl=64 time=436 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=6 ttl=64 time=391 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=7 ttl=64 time=397 ms

And it does! Latency is horrid (and there’s a bunch of tx artifacts that cause issues for us) – but both of those things are problems for later. Let’s see how it handles a TCP connection by firing off a quick cURL across the Pigeon network:

$ curl http://[2602:810:6008:401:8e1f:64ff:fe35:4001]:8000/testing.txt
The rock dove (Columba livia), also known as the common pigeon or rock pigeon
(but see also Petrophassa), is a member of the bird family Columbidae (doves
and pigeons).

As expected, our “remote” end here running the server reports the correct peer IP address, which is another indication (beyond the log messages and blinking LEDs) that we’re routing over our TUN interface.

Serving HTTP on 2602:810:6008:401:8e1f:64ff:fe35:4001 port 8000 (http://[2602:810:6008:401:8e1f:64ff:fe35:4001]:8000/) ...
2602:810:6008:401:8e1f:64ff:fe35:4002 - - [28/May/2026 12:53:21] "GET /testing.txt HTTP/1.1" 200 -

That … worked? First shot! Nice! It’s pretty slow and seems like we have a lot of packet loss, but it does, however, beg the question – can it nethack?

nethack!

Yes! It can nethack! No clickbait here. The way I went about this one is a bit anit-cimatic – I set up a nethack server (using inetd in this case) on one of the hosts’ pigeon0 network interface, and hit that port over RF from the other:

However, when playing it, it becomes very obvious (as you can likely see) that there’s a fair amount of packet loss (understandable) and probably some packet collisions taking place.

iperf

Let’s try and put a number to exactly how bad the bandwidth and packet loss is by running iperf between the two pigeon hosts over rf:

$ iperf -c 2602:810:6008:401:8e1f:64ff:fe35:4002
------------------------------------------------------------
Client connecting to 2602:810:6008:401:8e1f:64ff:fe35:4002, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[ 1] local 2602:810:6008:401:: port 58248 connected with 2602:810:6008:401:8e1f:64ff:fe35:4002 port 5001
[ ID] Interval Transfer Bandwidth
[ 1] 0.0000-20.2348 sec 76.8 KBytes 31.1 Kbits/sec

Shockingly, not nearly as bad as I thought it was going to be. Given I’ve spent exactly zero time making this operate to a level that I would call acceptable, this is a very fucking solid start. I expect I could get that number up if I spent a few weeks on it – it’s just not been a priority at any point yet (and the first time I’ve instrumented it, even!).

This’ll be good enough to get started. Let’s see what else we can pull off here.

IP multicast to some rtl-sdrs

Back when I designed what I wanted Mode A to look like, I intentionally picked a signal bandwidth that could be received by an rtl-sdr – so let’s put that to use. It may go without saying, but just to say it – the rtl-sdr can not transmit, so this will be capable of receiving pigeon frames – but not sending any in reply.

However, this means I can use a bunch of low-cost computers (raspberry pi-class), and low-cost SDRs (rtl-sdr) and still receive IP traffic from transmitting pigeon network stations. This could be a lot of fun for things like fountain coding a data stream, or adapting multicast streaming protocols to work over RF links. Anywho, I swapped my “far” end to an rtl-sdr (one config file change!), and figured I’d start with some (basic) multicast traffic, transmitting the time once a second:

$ while [ true ]; do
 echo $(date +%s) \
 | socat - UDP6-DATAGRAM:[ff02::114%pigeon0]:62804
 sleep 1
done

If I had more time to burn, I was planning on bridging APRS traffic to UDP multicast within a pigeon network subnet. However, since I’m already 4 years late on this blog post, I figured this would be enough for now (and you can imagine that fun project in this space if you so wish!)

I fired up pigeond again (except this time connected to an rtl-sdr), and was pleasantly surprised to be greeted by some decoded traffic right off the bat:

⪧ [k3xec/mn] 8c:1f:64:35:40:02 ⇢ 00:00:00:00:00:00 ipv6 fe80::23ee:2969:53f7:b332 ⇢ ff02::114 17 (UDP - User Datagram)
⪧ [k3xec/mn] 8c:1f:64:35:40:02 ⇢ 00:00:00:00:00:00 ipv6 fe80::23ee:2969:53f7:b332 ⇢ ff02::114 17 (UDP - User Datagram)
⪧ [k3xec/mn] 8c:1f:64:35:40:02 ⇢ 00:00:00:00:00:00 ipv6 fe80::23ee:2969:53f7:b332 ⇢ ff02::114 17 (UDP - User Datagram)
⪧ [k3xec/mn] 8c:1f:64:35:40:02 ⇢ 00:00:00:00:00:00 ipv6 fe80::23ee:2969:53f7:b332 ⇢ ff02::114 17 (UDP - User Datagram)

Of course, I took a tcpdump to confirm for completeness sake that the traffic actually made it out of our TUN interface:

$ tcpdump -i pigeon0
22:39:34.808705 IP6 (flowlabel 0x92a0e, hlim 1, next-header UDP (17), payload length 19) fe80::23ee:2969:53f7:b332.35911 > ff02::114.62804: [udp sum ok] UDP, length 11
22:39:36.429887 IP6 (flowlabel 0x4dc84, hlim 1, next-header UDP (17), payload length 19) fe80::23ee:2969:53f7:b332.50026 > ff02::114.62804: [udp sum ok] UDP, length 11
22:39:39.365977 IP6 (flowlabel 0x224d5, hlim 1, next-header UDP (17), payload length 19) fe80::23ee:2969:53f7:b332.36308 > ff02::114.62804: [udp sum ok] UDP, length 11
22:39:40.944889 IP6 (flowlabel 0x4721c, hlim 1, next-header UDP (17), payload length 19) fe80::23ee:2969:53f7:b332.35003 > ff02::114.62804: [udp sum ok] UDP, length 11

Looks great! tcpdump is showing multicast packets show up (as we assumed they would), on the pigeon0 interface, on the machine connected to an rtl-sdr. Of course, any replies will get sent to the bit bucket, but it can definitely decode things just fine! Very fucking cool.

Well right, ok! Let’s go back to two rx/tx radios, and see what we can do with our newfound network stack over ham radio frequencies – let’s try to do some fun (and traditional!) ham radio things with it!

Winlink

Winlink is a ham radio mail relay system for ham radio operators to send, receive or relay mail over the internet, or RF (usually HF or VHF/2M). Winlink relays are accessible via whatever transport you can find – most commonly telnet (using the internet), ax.25 (usually 2m VHF) or VARA HF (unsurprisingly, on HF). I use pat as my Winlink client – it’s written in Go, doesn’t require windows, and is just generally nice to work with.

Let’s try the easy thing first – let’s connect by proxying the Winlink server into the pigeon network using socat (lightly edited to remove date/times)

$ pat connect pigeon
Connecting to WL2K (telnet)...
Connected to [2602:810:6008:401:8e1f:64ff:fe35:4002]:8772 (tcp)
[WL2K-5.0-B2FWIHJM$]
;PQ: 54509561
CMS>
>FC EM OLU6BP5HKMG2 240 205 0
>F> 95
FS Y
Remote accepted OLU6BP5HKMG2
Transmitting [Hello, World] [offset 0]
Hello, World: 100%
FF
>FQ
Disconnected.
$

Lo and behold, shortly after, I got this delightful message to my email address, relayed in from WINLINK:

From: K3XEC@winlink.org
Reply-To: K3XEC@winlink.org
Subject: Hello, World
To: paultag@[...]
Message-ID: <OLU6BP5HKMG2@winlink.org>
MIME-Version: 1.0
X-MARSPrecedence: Routine
X-WL2KPrecedence: Routine
Content-Type: text/plain
Content-Transfer-Encoding: 8bit

Hello, World!

The only shame is I won’t be able to check in to a winlink wednesday using this scheme unless I further proxy this message over AX.25 instead of relaying to Winlink’s servers over telnet (which, to be fair, is definitely also possible – I just got lazy when I glued this one together – see note above about being 4 years late on this post).

But, you know, connecting to a host that is using socat to proxy a connection to an internet resource is interesting but – you know what, fuck it – hang on, dear reader – let’s bang a hard left turn and just ship this thing hard and directly connect it to the internet. Let’s take our dinky, home-built PHY and Layer 2 and see if we can wire it directly into the internet – something that, every time I go to think about it, reminds me of Tim FitzHigham and his crapper.

Crossing the english channel in a bathtub

Ok, ok. I decided to bury the lede a bit here – I didn’t mention that the side.band network is currently BGP announced. Although we haven’t used it – this does mean that we’re most of the way to sending packets to the wider internet, and we should be able to “just” fix a few routing tables, and see packets begin to flow.

After tweaking the local routing tables (and restarting pigeond for good measure), I decided to test my newfound connectivity by pinging something over our new network transport.

ping github

Why don’t we start with the world’s premier software engineering platform, operated by one of the largest companies in the world, GitHub! After all, they have an all knowing (and, apparently, arguably sentiant?) AI on hand to instantly and automatically fix any stray reliability issues in the background, so we should definitely see replies right off the bat:

$ ping6 github.com
ping6: github.com: Address family for hostname not supported

Wait, oh no – that can’t be right?

After all, it’s 2026, and both Google and CloudFlare (in North America) are reporting over half of all traffic they see is IPv6 – and GitHub still doesn’t support IPv6? Definitely not, this is for sure a bug with my code or network.

lets ping something that supports ipv6 instead

That being said, just for completeness sake, since that error is also given when there’s no IPv6 DNS record, let’s go ahead and double check with Hurricane Electric too, you know, just to be sure.

$ ping6 he.net
PING he.net (2001:470:0:503::2) 56 data bytes
64 bytes from he.net (2001:470:0:503::2): icmp_seq=1 ttl=53 time=514 ms
64 bytes from he.net (2001:470:0:503::2): icmp_seq=2 ttl=53 time=230 ms
64 bytes from he.net (2001:470:0:503::2): icmp_seq=3 ttl=53 time=248 ms
64 bytes from he.net (2001:470:0:503::2): icmp_seq=4 ttl=53 time=246 ms
64 bytes from he.net (2001:470:0:503::2): icmp_seq=5 ttl=53 time=265 ms
64 bytes from he.net (2001:470:0:503::2): icmp_seq=6 ttl=53 time=240 ms

Well, shit. Right, OK, i’ll be damned. 18 years in and GitHub still can’t crack that nut.

cURL works!

Right, anyway, yes, back on track – good news! Our uplink is up and routing, and wait, holy shit! Check it out! pigeon is exchanging packets with the internet and no one is any the wiser! Literlaly amazing. Let’s try a cURL across the internet now (although no TLS allowed, so, http only for now):

$ curl -6 -I http://facebook.com
HTTP/1.1 301 Moved Permanently
Location: https://facebook.com/
Content-Type: text/plain
Server: proxygen-bolt
Connection: keep-alive
Content-Length: 0

IRC works, too

Sweeeeet. That all works! Forget HTTP, let’s do some other 90’s era stuff, it’s high-time to log into IRC with a quick /connect -notls, and see what’s going on in the #debian-hams channel – pleased that I got online fairly quickly, and was able to even talk to myself!

THE GOPHERSPACE

Naturally, let’s keep this train of nostalga running, and give the 2026 gopherspace a shot.

I know the kind folks over at tilde.town (hello, townies!) have a robust gopherspace, so let’s give it a dial! Let’s try and see if we can load vilmibm’s slug over gopher:

Yes! I forgot to make this one a video, so no gif. I did wind up having a bit if trouble with a few gopher clients and IPv6 support – I may send some patches if I can find the time.

So, what’s next?

Alright, that’s it. I have a few more fun ideas but they’re going to have to wait for another day. Carrying IP is fun and all but kinda not the point behind pigeon, after all. Rather than trying to make this into “a thing”, I’m planning on exploring the loose ends first – different types of modulation schemes (like QAM-NUC), implementing LDPC error correction and some layer 2 logic into the pigeond (like switching traffic, and gain control). I also plan on spending some time with my (currently, very basic) simulator to better dial in tradeoffs throughout the stack.

Since, structurally, pigeon is something I feel like I can work with, I’m hoping i’ll be able to find the time for some (much smaller!) followup posts without it taking 4 years this time. If I do, they’ll show up under the pigeon tag – and I’ll be sure to update this post with a link below (and the intro post).

I’m hoping that this series (which was supposed to be one post) was helpful to someone out there – if it was, feel free to reach out and let me know!

  •  

Paul Tagliamonte: can you hear me now? good! (Part 11/12) 🕊️

🕊️ This post is part of a series called "Pigeon". If this is the first post you've found, it'd be worth reading the intro post first and then looking over all posts in the series.

If you're looking for it, the intro to the Link (layer 2) that this belongs at a high level and listing of the parts that make it up (including this one) is on the link post.

Built-in to the pigeon link protocol is a message type called cal (short for, you guessed it, calibration). A pigeon frame with a type of cal (which is 0x02) carries a JSON encoded payload in the body, which can either be a beacon, requesting signal reports in response, or a report, describing the received beacons.

This serves a few interesting purposes – firstly, network operators can better understand the coverage footprint, propagation under different conditions, and how gain impacts reception when tuning for the lowest practical power levels. Secondly, this can be used (and I plan to eventually implement!) to construct a mapping of minimum power level and peer mac address to dynamically control the transmission power based on the destination station.

That being said, for now, all I’ve used this for is getting a rough sense for what gain value(s) make sense between two nodes (manually). In the future, beyond all the fancy neighbor gain stuff, I plan to wire this into the daemon to happen automatically, “debouncing” for beacon and report messages, such that transmitting stations only beacon, and receiving stations only report a max of once over some time period for a given peer.

Version

Given all the above, I do intend to make some massive changes to this protocol (I promise to blog all about it) when I get around to hacking on switching Layer 2 frames within a network segment. Just to avoid having to dig myself out of a hole later, I’m going to explicitly send (and check) the version field to avoid having a big “flag day” switchover or needing to use a new link type.

Version ID Description
V1this version of the cal protocol

Location

Both flavors of cal messages (beacon and report) may contain a location, which is the location that the beacon was transmitted, or for or the location where the beacon was heard for a response. This can be used to derive a coverage map and to (operationally) better understand what stations should be within range, and generally what gain level(s) are effective.

All fields assume WGS84 latitude and longitude values, and elevation is distance, in meters, above the WGS84 ellipsoid – NOT height above sea level, or altitude above the ground.

Field Description
latWGS84 Latitude
lonWGS84 Longitude
elevationheight, in meters above the WGS84 ellipsoid

Sequence

Each beacon contains a Sequence identifier, which is used to communicate which message number is being heard, and how many total were transmitted by the originating station. The current approach with Beacon messages is to transmit some number of Beacon messages at different gain levels, each with a unique Sequence identifier.

Field Description
numberbeacon sequence number
totaltotal number of beacons transmitted

Gains

Recorded gain setting(s). For a Beacon this indicates the gain settings (which, in spite of its name, includes things like amplifiers, or attenuators). Changing this over different Beacon frames enables a better understanding of what an appropriate gain level is for the transmitting station over time.

Field Description
namegain stage name
dbgain value, in dBm

Cal

All messages contained in a cal frame are of this type. The type field communicates if this is a Beacon or Report message type.

Type Description
beaconsent intermittently by idle stations
reportreception report in response to a beacon

Beacon

A beacon message may be sent periodically by pigeon nodes capable of transmitting to announce their prescience to peers and, implicitly, to receive signal reports from nearby listeners who are capable and configured to transmit reports.

The beacon JSON message is made up of the following fields:

Field Description
versionversion enum value
gainsgains object
sequencesequence number
locationlocation object

An example beacon looks, unsupprisingly, as follows:

{
 "type": "beacon",
 "version": "V1",
 "sequence": {
 "number": 2,
 "total": 5
 },
 "gains": []
}

Report

A report message may be sent in response to a beacon message by pigeon nodes capable of receiving and transmitting to assist with setting the lowest usable gain value, and to better understand the area of coverage and propagation.

The report JSON message is made up of the following fields:

Field Description
versionversion object
locationlocation object

An example report looks as follows:

{
 "type": "report",
}

With all that out of the way

lets send some ip →

  •  

Paul Tagliamonte: You would never break the chain (Part 10/12) 🕊️

🕊️ This post is part of a series called "Pigeon". If this is the first post you've found, it'd be worth reading the intro post first and then looking over all posts in the series.

Now that we have a working Layer 1, we have a way to send a block of bits from one place to anyone who cares to listen to us. This is very welcome news, but we are now facing a new, different and just as fun question – what shape should that data take?

⏳ Need a bit more of a crash course on what "Layer 1" and "Layer 2" mean? No problem, I wrote up short summary here to help.

Given our incredibly limited functionality of our nodes, we could definitely skip all this work and just stuff an IP packet into the link; but I decided to not since I am (eventually) interested in adding some sort of spanning tree-like protocol to implement network switching so not all nodes need to communicate directly with all other nodes – but that day is not today.

Given i’m going to stub most of that out, let’s take a look at what some similar Layer 2 protocols use – things like Ethernet or WiFi frames. Both contain structured information regarding the transmitter, desired recipient, type of data, and the higher-level data itself (such as IP packets). As a result of attempting to learn from others, the Pigeon Layer 2 (called, simply, “link”) is also split into a fixed-length header, followed by the contents described by the header.

dst mac
src mac
callsign
length
payload

The header is a fixed-length (23 byte) structure, which contains the source MAC address (src mac), destination MAC address (dst mac), the ITU coordinated ham radio callsign of the control operator of this message (callsign), the type of payload to follow (type; defined below), and the length of the data to follow the header (length as a 16 bit big-endian unsigned integer).

The type field indicates how the payload is to be interpreted – currently I’ve only defined 3 possible payload types so far:

Type Description
0x01Raw (testing only)
0x02Cal
0x04Ipv6

Keen observers will perhaps infer that there used to be an Ipv4 type at 0x03 – which is true – however, i’ve since removed it since i’ve never once used it and the codepath was more trouble than it was worth. As is my wont, I’ve optend to just lean into Ipv6-only IP transport – it’s easy enough to shim ipv4 in, if someone REALLY wanted to using something like 64:ff9b:1::/48 and a bit of code in the transmitter/receiver (or even using something like jool and unbound’s dns64-prefix at the router). I don’t think I’ll bring it back, but just in case I have to for some reason in the future, it’s there.

Additionally, friends of the pod may also recognize that this structure is basically the exact same structure as what I had in PACKRAT, which, is also true. I started this project off maintaining interoperability in the Layer 2 for pigeon and packrat, but at some point just gave up on it during one of the many cleanups. I’m hopeful I can maintain compatibility going forward, and that won’t have to muck with this header too much more. We’ll see what happens once I start to push the bounds of what is possible with pigeon.

Hopefully it feels like carrying IP data inside this frame to be a pretty self-explanatory exercise – the 0th byte of the payload is the 0th byte of an IPv6 header (followed by all the usual stuff, like UDP or TCP header(s) and any carried data, just like you’d find anywhere else.

Pigeon’s calabration protocol →

  •  

Paul Tagliamonte: Mode A (Part 9/12) 🕊️

🕊️ This post is part of a series called "Pigeon". If this is the first post you've found, it'd be worth reading the intro post first and then looking over all posts in the series.

If you're looking for it, the intro to the PHY (layer 1) that this belongs at a high level and listing of the parts that make it up (including this one) is on the phy post.

While developing Pigeon, I’ve called the group of all the configuration of the Layer 1 PHY parameters the “Mode”. I’ve experimented with a few different “modes”, but one in particular has been the most resilient to the innumerable mistakes and bugs i’ve wrought into existence – and that is the first mode I wrote down, “Mode A”. This is even (mostly) backwards compatible to my original Go implementation of Pigeon Mode A (back in 2022) over the air, and has largely withstood the problems I’ve thrown at it.

I’ve removed the bulk of the support I wrote out for other modes, but i’m likely to bring them back over time as I use pigeon to learn more (such as “Mode B” (QAM-16), “Mode C” (QAM-16 NUC), and “Mode AW” which is the exact same as Mode A, except 5MHz in bandwidth. More to come on those as I get further along – but for now let’s braindump the parameters i’ve picked out for Mode A:

Attribute Value Description
Rate 2.5 MHz Sampling Rate / Bandwidth
LCG 3149721335 LCG "RNG" whitening constant (randomly selected)
Preamble seq=16, order=4, count=2 (this is as-written in the preamble post)
Modulation QPSK/QAM-4 2 bits per data subcarrier
FFT Size 64
Cyc Len 16 Cyclic Prefix length (16 IQ samples)
Symbols 168 Number of OFDM Symbols
LDPC Table 802.3an (this is as-written in the ldpc post)
Raw Bits 14448 1806 bytes (168 symbols, 86 data bits per symbol)
LDPC Count 7 Number of packed LDPC encoded messages
Data Bits 12061 1507 bytes

The last bit to describe here is the Subcarrier Plan. The plan is ordered “negative first” (meaning the 0th bin in-memory is the most negative frequency domain bin of the fft), and within a Mode A OFDM symbol, there are 64 frequency domain bins (so, just to make it explicit: 64 ‘subcarrier usages’ that make up our Mode A ‘subcarrier plan’).

We’ll follow the same structure and conventions that we went through in the post all about OFDM Symbols – which means, we’ll need to place our guard bins, data bins, and pilot bins. I’ll include a copy-paste-able version of the images to follow at the end.

Guard Bins

First up, let’s place our guard bins. As we’ve already gone over, we’re looking to clear some space right up against the high and low end of the frequency range, so let’s go ahead and do that:

I gave up the center bin (0 Hz) and 8 of the 64 bits on each side (1/4 of the signal!) to give myself a bit of elbow room. This is perhaps definitely a bit overkill, but it’s been an extremely robust choice. If you multiply that through, this accounts for 312.5 kHz of frequency domain “padding” at the high and low end of the bandwidth, or 625.0 kHz of bandwidth which is not to be used.

Pilot Bins

Next up was the pilot bins. We’ve already gone over the purpose (and use) of our pilots, but I’ve found there to be an art to the placement of the pilots. Interpolation between pilot bins has turned out to be very reliable, but extrapolation, on the other hand, has been a major pain, for reasons I don’t fully understand yet.

My intent in placement was to pick out roughly even stretches of data bins bracketed between pilots, with as few data subcarriers as practical “outside” of a pilot (using extrapolation). I’ve played a bit with my AGWN simulator(s), as well as logging errors between two SDRs, and the configuration I have this in has been fairly resillant (for whatever reason), and withstood a few rounds of tweaking.

Data Bins

Almost as an afterthought – all of the remaining bins become data bins.

This puts the total number of data bins at 43, which, since Mode A carries data in QPSK/QAM-4 (two bits per data subcarrier), means we can carry 86 bits of data per OFDM symbol. That fairly modest capacity is largely due to the modulation scheme (or fft size, but increasing that has been … fraught) we’re using for Mode A – but I’ve made up for it by including 168 OFDM symbols in a single burst in order to have enough data to carry IP traffic without splitting the packet into two bursts.

With all that designed and on paper, we’re ready to start to tackle the next layer up – our Layer 2, named, creatively, “link”.

Let’s send some link layer data →


Following along at home? Nice! As promised, I've put the full plan copy-pasted from the pigeon source tree below so that no one has to feel the need to transcribe this from the images above. Unlike most of the things I've "left to the reader", manual transcription from images is not a particularly useful task for anyone to do.

The following table is Mode A’s OFDM Subcarrier Plan. This is in negative first ordering (meaning the 0th member is the most negative fft bin, and the Nth is the highest frequency fft bin).

SubcarrierPlan([
 Guard,
 Guard,
 Guard,
 Guard,
 Guard,
 Guard,
 Guard,
 Guard,
 Data,
 Data,
 Data,
 Pilot(iq!(-1.0, 0.0)),
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Pilot(iq!(1.0, 0.0)),
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Guard,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Pilot(iq!(0.0, -1.0)),
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Data,
 Pilot(iq!(0.0, 1.0)),
 Data,
 Data,
 Data,
 Guard,
 Guard,
 Guard,
 Guard,
 Guard,
 Guard,
 Guard,
 Guard,
])
Still following along at home? Nicer! I've put the preamble sequence promised previously copy-pasted from the pigeon source tree below in case that's actually important (I don't think it is, but...).

The following table is Mode A’s frequency-domain preamble. This is, as above, in negative first ordering. I don’t actually think these values matter much (at all)? – but in case they do, here’s what I have. I muck with these a lot and haven’t found many changes in quality of detection or frequency correction yet.

[
 IQ::new(0.0, 0.0),
 IQ::new(0.0, 0.0),
 IQ::polar((TAU / 13.0) * 2.0, 1.0),
 IQ::polar((TAU / 13.0) * 3.0, 1.0),
 IQ::polar((TAU / 13.0) * 4.0, 1.0),
 IQ::polar((TAU / 13.0) * 5.0, 1.0),
 IQ::polar((TAU / 13.0) * 6.0, 1.0),
 IQ::polar((TAU / 13.0) * 7.0, 1.0),
 IQ::polar((TAU / 13.0) * 8.0, 1.0),
 IQ::polar((TAU / 13.0) * 9.0, 1.0),
 IQ::polar((TAU / 13.0) * 10.0, 1.0),
 IQ::polar((TAU / 13.0) * 11.0, 1.0),
 IQ::polar((TAU / 13.0) * 12.0, 1.0),
 IQ::polar((TAU / 13.0) * 13.0, 1.0),
 IQ::new(0.0, 0.0),
 IQ::new(0.0, 0.0),
]

Let’s send some link layer data →

  •  

Paul Tagliamonte: wrapping it all up (Part 8/12) 🕊️

🕊️ This post is part of a series called "Pigeon". If this is the first post you've found, it'd be worth reading the intro post first and then looking over all posts in the series.

If you're looking for it, the intro to the PHY (layer 1) that this belongs at a high level and listing of the parts that make it up (including this one) is on the phy post.

The time has come.

If you’re following along at home, we now have all the basics we need to glue these parts together and see what this looks like.

We’re going to build the highest-level constructs for the PHY in code – something that takes some number of bytes in and writes out IQ samples fit for transmit over the airwaves (we’ll call this the Encoder), and something that takes chunks of IQ samples in, writing out decoded bytes (which we’ll call the Decoder).

Encoder

Let’s begin with the Encoder, since it’s slightly less involved. I’ve tried to make this a bit more accessible by drawing a diagram out before describing the order of operations, so that it’s possible to follow along visually.

While the process here can look like a lot, it’s really not that bad. We begin by taking the incoming bytes, converting the bytes into bits, and chunk those bits into parts which are sized to fit completely within an LDPC message. We will then encode incoming data into LDPC messages, using our configured LDPC Matrix (the table we appropriated from 802.3an). Next, we apply whitning over all the bits in our encoded (and packed) LDPC messages, using our configured whitening constant. In the case of QPSK, pairs of bits will then be modulated into a QAM subcarrier, where each QAM point represents a range of bits in the message. We’ll go through each of those modulated IQ subcarriers, and set each corresponding data subcarrier in order, for each OFDM symbol contained in the pigeon Burst. The preamble configuration is then used to generate (or, more likely, can be used at startup to precompute) the Schmidl-Cox preamble, which is written to the first IQ samples in our output IQ buffer. Finally, we will do a series of inverse FFT operations to convert each OFDM symbol to the time domain, including their cyclic prefix.

Let’s take a look at doing that, but in code this time now:

// (lightly edited for clarity)
impl Encoder {
 ..

 /// Encode the provided bits into the output time-domain IQ samples.
 fn encode(
 &mut self,
 dst: &mut [IQ],
 src: &Vector,
 ) -> Result<Burst, Error> {
 let src = {
 let mut raw = Vector::new(self.fec.message_len());

 // Set `raw`'s data bits, compute and set LDPC
 // checkbits.
 self.fec.add(&mut raw, src);

 // Apply whitening, and return
 raw.xor(&self.whitening)
 };

 // copy in the precomputed schmidl-cox preamble to `dst`
 let preamble_len = self.preamble_iq.len();
 dst[..preamble_len].copy_from_slice(&self.preamble_iq);

 // allocate a new (frequency domain) 'Burst' container.
 let mut burst = Burst::new(
 &self.mode.ofdm.plan,
 self.mode.ofdm.symbols
 );

 // modulate bits from 'src' as iq, and set each
 // data subcarrier for each ofdm symbol in the
 // burst.
 self.burst_encoder.multiplex(&mut burst, &src);

 // convert from frequency-domain data into time
 // domain iq samples, writing out ofdm symbols
 // and cyclic prefixes to `dst`.
 self.burst_encoder
 .transform(&mut dst[preamble_len..], &burst)?;

 // normalize all IQ samples; the maximum magnitude
 // in the IQ buffer may be very small, which weakens
 // our transmitted signal. Scale all IQ samples such
 // that the maximum IQ sample magnitude will be '1.0'.
 dst.norm();

 Ok(burst)
 }
}

Using the Encoder should hopefully be fairly straightforward – we’ll give it a bag of bytes, and get back some IQ samples that we can ask our nearest SDR to transmit.

As for what happens on the other end?

Decoder

Next up is the mirror image of our Encoder – the, imaginatively named, Decoder. The Decoder is slightly more involved (since it has to find the packet in the IQ stream, as well as correct for channel error(s)), so we’ll do the same thing as above – start with a diagram. My hope is going over the Encoder first helps us only really focus on the “new” stuff, otherwise it should feel like running the Encoder backwards.

Here, we start with an incoming stream of IQ, where we will process scan detections as they come in from our Schmidl-Cox detector and burst Scanner. This will give us a “snippit” of IQ, sized to exactly our Burst. We’ll begin to correct our IQ samples by first doing frequency estimation and correction in the time domain using our preamble and ofdm configuration. We’ll then do a series of inverse FFTs to extract each OFDM symbol in our Burst, where we can then do channel estimation and correction. With the OFDM symbols (hopefully) good enough, we can now map each data subcarrier back to bits, and unapply whitning. The resulting bits are then chunked back up into LDPC messages, which are then checked, and concatanated data extracted. Finally the bits are turned back into bytes, which are written to our output buffer.

However, before we get into the code to do this – there’s one last detail. We know bursts won’t overlap (if they do, it’s likely not possible to recover right now – even though other PHYs can and do), so any time we see something we believe to be a burst, we can skip ahead by the burst’s (constant) length within the IQ, and avoid trying to decode anything else in there.

The nice side-effect here is this also gives us an interesting property for the Decoder – namely, we know the maximum number of Burst detections we can get for a given block of incoming IQ data if they were packed end-to-end – and we can pre-allocate the memory we need, avoiding allocations for every demodulation attempt (which may or may not even be a valid Burst).

This pre-allocated block of memory to hold the burst’s data is something that I’ve called a frame buffer internally. Each frame buffer contains exactly sized buffers to hold decoded information from the burst – an iq buffer that is exactly the same number of samples required to encode the preamble and data, exactly the number of bits needed to store pre and post FEC data, pre-allocated byte array, etc.

Not shockingly, the code looks like this:

#[derive(Clone)]
pub struct FrameBuffer {
 /// Corrected IQ samples
 pub samples: Samples,

 /// post-correction OFDM burst
 pub burst: Burst,

 /// demodulated bits from the OFDM burst
 pub bits: Vector,

 /// demodulated bits from the OFDM burst,
 /// after FEC, and cleaned
 pub raw_bits: Vector,

 /// Layer 2 contents of the Frame
 pub contents: Vec<u8>,
}

Of course, that alone is handy – but we need to use them. So let’s go ahead and do what we promised above – each Decoder uses a fixed number of pre-allocated FrameBuffers to store packets in-flight, packed into what is, creatively, called FrameBuffers within my code.

As an aside, I likely should have called this a Memory Pool, since that’s the common and accepted name for this design pattern – but being stuck with unfortunate names is the burden of those of us who stumble into sensible ideas over time. The only nuance here is that I use the pools strictly sequentially – we only “save” the FrameBuffer if the LDPC checksum is correct, allowing us to only keep track of how many successful packets we have and being able to get the valid FrameBuffers, rather than storing a handle to each FrameBuffer as we go – a promise that most memory pools do not make, since blocks can usually be taken and returned in any order.

Let’s go ahead and do the whole Decoder dance now:

// (lightly edited for clarity)

impl Decoder {
 ..

 /// Process incoming IQ for Pigeon Bursts, and
 /// demodulate them.
 pub fn decode(
 &mut self,
 buf: &[IQ],
 ) -> Result<Vec<(Detection, &FrameBuffer)>, Error> {
 let mut ret = Vec::new();
 let mode = self.scanner.mode().clone();

 // reset the "valid frame buffer count" back to 0
 self.frames.reset();

 // call the scanner and get scan detections for
 // this block of iq (`buf`)
 for detection in self.scanner.scan(buf) {
 // for each detection, we're (only) going to process
 // the iq snippit, but pass along the metadata
 // such as SNR.
 let ScanDetection {
 snippit,
 snr,
 range,
 m,
 } = detection;

 // grab the next free frame buffer to work within.
 let frame_buffer = self.frames.next_mut();

 // Copy the snippit into the frame buffer (a mutable
 // location)
 frame_buffer.samples.copy_from_slice(snippit);

 // estimate the frequency offset based on the
 // Burst's Schmidl-Cox preamble.
 let preamble_fo = preamble::estimate_frequency_offset(
 &mode.preamble,
 mode.rate,
 &frame_buffer.samples[..mode.preamble.samples()],
 );

 // Shift the IQ stream by the estimated frequency
 // offset -- hopefully we're closer to 0Hz
 frame_buffer.samples.shift(mode.rate, preamble_fo);

 // estimate the frequency offset based on the
 // each burst's **cyclic prefix** -- exactly like
 // we did with the Burst Schmidl-Cox preamble,
 // but this time on each OFDM symbol.
 let ofdm_fo = ofdm::estimate_frequency_offset(
 &mode.ofdm,
 mode.rate,
 &frame_buffer.samples[mode.preamble.samples()..],
 );

 // Shift the IQ stream closer yet; hopefully this
 // is a very small nudge even closer still to 0Hz.
 frame_buffer.samples.shift(mode.rate, ofdm_fo);

 // Do a bunch of inverse fft operations for each
 // OFDM symbol, filling the frequency-domain Symbol
 // structs in `frame_buffer.burst` (Burst) struct.
 //
 // this will also do channel estimation and
 // correction before returning.
 self
 .decoder
 .transform(
 &mut frame_buffer.burst,
 &frame_buffer.samples[mode.preamble.samples()..],
 )?;

 // "demultiplex" each data subcarrier's frequency-domain
 // IQ constellation point, setting the correct bit range.
 self.decoder.demultiplex(
 &mut frame_buffer.raw_bits,
 &frame_buffer.burst
 );

 // unapply whitening by XOR-ing the buffer with
 // the well-known whitening vector.
 frame_buffer.raw_bits = frame_buffer.raw_bits.xor(
 &self.whitening);

 // verify that the LDPC message(s) are all correct,
 // and if so, concatanate the the data bits (no check
 // bits) to the `bits` vector.
 if self.fec.decode(
 &mut frame_buffer.bits,
 &frame_buffer.raw_bits
 ).is_err() {
 // this is where invalid packets fail. we gave it a good go.
 // next packet please.
 continue;
 }

 // copy the raw bits out, as bytes, to the `contents` buffer.
 frame_buffer.bits.copy_as_bytes(&mut frame_buffer.contents);

 // store metadata/metrics on the demodulation.
 ret.push(Detection {
 m,
 snr,
 index: range.start,
 });

 // save the contents of this frame buffer (don't
 // reuse this buffer next go-around).
 self.frames.save();
 }

 // We're going to take out the borrow on the frame at
 // the end since we don't want to deal with telling the
 // compiler via code gymnastics that the mut and non-mut
 // borrows are OK since they're non-overlapping.
 Ok(ret.into_iter().zip(self.frames.iter()).collect())
 }
}

Phew. That was kinda a lot. In fact it’s basically the whole thing. This function is as close to “how do you read an OFDM packet” as it gets, and perhaps the most important part of this whole series. Beyond that, though, this is a huge conceptual unlock. This means we now have an incredibly powerful primitive; the ability to take bytes and go to/from IQ samples over the air.

Let’s talk about pigeon modes →

  •  

Amazon Takes Up to $150 Off M5 MacBook Air

Amazon is taking up to $150 off multiple models of the M5 MacBook Air, including both 13-inch and 15-inch models. These are the best prices we've seen on the M5 MacBook Air in the wake of Apple's summertime price hikes.

Note: MacRumors is an affiliate partner with Amazon. When you click a link and make a purchase, we may receive a small payment, which helps us keep the site running.

New highlights include a pair of 15-inch M5 MacBook Air models at $150 off, starting with the 16GB/512GB model for $1,349.00 in Midnight, down from $1,499.00. You can also get the 16GB/1TB model for $1,649.00, down from $1,799.00, which is $50 cheaper when compared to the deals we tracked towards the end of August.




In terms of 13-inch models, Amazon has the 16GB/1TB 13-inch MacBook Air for $1,449.00, down from $1,599.00. This one is available in two colors on Amazon, and it's accompanied by the 24GB/1TB model for $100 off.




If you're on the hunt for more discounts, be sure to visit our Apple Deals roundup where we recap the best Apple-related bargains of the past week.




Deals Newsletter


Interested in hearing more about the best deals you can find in 2026? Sign up for our Deals Newsletter and we'll keep you updated so you don't miss the biggest deals of the season!




Related Roundup: Apple Deals

This article, "Amazon Takes Up to $150 Off M5 MacBook Air" first appeared on MacRumors.com

Discuss this article in our forums

  •  

Amazon Introduces First Pre-Order Discount on New Mac Studio, Alongside Mac Mini Deals

Amazon last week introduced the first cash discounts on Apple's brand new Mac mini, and today the M5 Max Mac Studio has joined in on the discounts. You can get this model, which includes 36GB RAM and a 512GB SSD, on sale for $2,449.99, a $49 pre-order discount.

Note: MacRumors is an affiliate partner with Amazon. When you click a link and make a purchase, we may receive a small payment, which helps us keep the site running.

All of these deals are pre-order discounts on the 2026 Mac mini and Mac Studio, which officially launch on September 22. Regarding the Mac mini, you can get the 16GB RAM/256GB SSD Mac mini for $879.99, down from $899.00, and the 16GB RAM/512GB SSD model for $1,069.99, down from $1,099.00.






In terms of upgrades, Apple said the Mac mini with the M6 chip delivers up to 40% faster CPU performance, up to 4× faster performance for AI tasks in particular, up to 2× faster graphics performance, and up to 2× faster storage speeds compared to the previous-generation model with the 10-core M4 chip, 32GB of unified memory, and 2TB of storage.

If you're on the hunt for more discounts, be sure to visit our Apple Deals roundup where we recap the best Apple-related bargains of the past week.




Deals Newsletter


Interested in hearing more about the best deals you can find in 2026? Sign up for our Deals Newsletter and we'll keep you updated so you don't miss the biggest deals of the season!




Related Roundup: Apple Deals

This article, "Amazon Introduces First Pre-Order Discount on New Mac Studio, Alongside Mac Mini Deals" first appeared on MacRumors.com

Discuss this article in our forums

  •  

BSD Release: FreeBSD 14.5

The DistroWatch news feed is brought to you by TUXEDO COMPUTERS. The FreeBSD project has published an update to FreeBSD's 14.x series. The new version, 14.5, provides several fixes and introduces some changes to the userland utilities. "The rc.firewall script now supports reading IP addresses or subnets from on-disk files for the firewall_allowservices and firewall_trusted list variables. Elements that....
  •  

Foldable iPhone Development History and Price Revealed in New Report

Former Apple CEO Tim Cook played a major role in the development of the foldable iPhone, which could reach around $3,000 with storage upgrades, according to new details shared by Bloomberg's Mark Gurman.


Early in the development of the foldable iPhone, the company reportedly targeted a starting retail price of $1,999, hoping to come under the "potentially controversial $2,000 barrier." The idea was to replicate the debut of the iPhone X in 2017, which started at $999.

Amid the impact of the global memory shortage, Apple is said to have recently discussed pricing the foldable at $2,199. Some storage configurations could approach $3,000. While the company anticipates some "sticker shock" for consumers, the willingness of customers to spend around $2,000 on iPhone models with upgraded storage convinced the company that an "upscale foldable device was worth bringing to market."

Gurman also revealed details about the history of the foldable iPhone inside Apple. Around 2020, Cook apparently returned from a visit to Asia "unusually energized" about foldable phones. During the trip, he saw growing numbers of consumers using foldable devices from the likes of Samsung and Huawei. He came to believe that Apple needed an equivalent offering in the market and pushed the company to accelerate its development efforts.

Apple's hardware engineering team had been studying foldable phones, displays, and related components for years, dating back to well before the launch of the first Galaxy Fold device in 2019. Before Cook's guidance, the project was mired by debates over the form that an Apple foldable should take, with one early concept being an iPad mini that could unfold into a larger tablet. Cook wanted the final device to be more mainstream in the form of a foldable iPhone, and his level of involvement in the project was unusual.

The project was conceived under Dan Riccio, who preceded John Ternus as head of hardware engineering. The company apparently prioritized resolving four main challenges: reducing the visibility of the display crease, improving hinge reliability, creating a new flexible cover glass for the inner display, and developing under-display camera technology.

The company eventually settled on a hinge system made using titanium and aluminum and custom cover glass developed with Corning. Despite being less durable than other existing iPhone models, Apple is said to believe that the construction quality of the foldable iPhone is industry-leading for the foldable market, and thinks it has an advantage over Android devices in terms of software.

Gurman restated several of the device's rumored specifications, including a 7.8-inch inner display, a 5.5-inch outer display, and a wide form-factor design. During development, Apple designers apparently compared the folded proportions of the device to a passport and the unfolded proportions to a Magic Trackpad. The short-and-wide design was chosen to provide a point of differentiation with rival foldable and generate consumer interest.

He reiterated that the foldable iPhone may be less durable than a conventional iPhone, with an inferior camera system and less battery life. Despite these drawbacks, Apple employees are said to believe "the company will sell every foldable phone it can produce."

Gurman also noted that the foldable iPhone's engineering complexity "makes it an ideal showcase" for new CEO John Ternus, following his career as Apple's hardware chief. Ternus was apparently a major champion of the device and played a major role to "push it over the finish line," alongside Cook.

Apple's foldable iPhone is expected to be announced tomorrow at its "Surprise and shine" event. See the full Bloomberg report for more information.
Related Roundup: iPhone Fold

This article, "Foldable iPhone Development History and Price Revealed in New Report" first appeared on MacRumors.com

Discuss this article in our forums

  •  

iPhone Ultra Touch ID 'Confirmed' in iOS 27? Not So Fast

Apple's iPhone Ultra is widely expected to feature Touch ID instead of Face ID, but references found in the iOS 27 beta probably shouldn't be treated as proof. Code sleuth pdfu has found Car Key strings that mention an iPhone in the same string as both Ultra Wideband and Touch ID, which they say "confirms" Touch ID for the foldable since "all existing iPhone models with an UWB chip, starting with iPhone 11, use Face ID."

However, Apple's codebase often has Touch ID references that aren't tied to specific hardware. Legacy terminology can also linger for years, with references to discontinued products like iPod still appearing in recent iOS code. So while Touch ID is expected, this detail doesn't confirm it.
Related Roundups: iOS 27, iPadOS 27

This article, "iPhone Ultra Touch ID 'Confirmed' in iOS 27? Not So Fast" first appeared on MacRumors.com

Discuss this article in our forums

  •  
❌