Add countryCode to MTRCommissioningParameters. (#27080)

This lets commissioners control what the Location of a device is set to at
commissioning time.
diff --git a/src/darwin/Framework/CHIP/MTRCommissioningParameters.h b/src/darwin/Framework/CHIP/MTRCommissioningParameters.h
index c16aaf6..f1cce0e 100644
--- a/src/darwin/Framework/CHIP/MTRCommissioningParameters.h
+++ b/src/darwin/Framework/CHIP/MTRCommissioningParameters.h
@@ -88,6 +88,14 @@
  */
 @property (nonatomic, assign) BOOL skipCommissioningComplete MTR_NEWLY_AVAILABLE;
 
+/**
+ * The country code to provide to the device during commissioning.
+ *
+ * If not nil, this must be a 2-character ISO 3166-1 country code, which the
+ * device can use to decide on things like radio communications bands.
+ */
+@property (nonatomic, copy, nullable) NSString * countryCode MTR_NEWLY_AVAILABLE;
+
 @end
 
 @interface MTRCommissioningParameters (Deprecated)
diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm
index e6388e0..2f01e49 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceController.mm
+++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm
@@ -31,6 +31,7 @@
 #import "MTRPersistentStorageDelegateBridge.h"
 #import "MTRSetupPayload.h"
 #import "NSDataSpanConversion.h"
+#import "NSStringSpanConversion.h"
 #import <setup_payload/ManualSetupPayloadGenerator.h>
 #import <setup_payload/SetupPayload.h>
 #import <zap-generated/MTRBaseClusters.h>
@@ -492,6 +493,9 @@
                 self, commissioningParams.deviceAttestationDelegate, timeoutSecs, shouldWaitAfterDeviceAttestation);
             params.SetDeviceAttestationDelegate(self->_deviceAttestationDelegateBridge);
         }
+        if (commissioningParams.countryCode != nil) {
+            params.SetCountryCode(AsCharSpan(commissioningParams.countryCode));
+        }
 
         chip::NodeId deviceId = [nodeID unsignedLongLongValue];
         self->_operationalCredentialsDelegate->SetDeviceID(deviceId);
diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
index 07999e0..eb33442 100644
--- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
+++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
@@ -96,10 +96,11 @@
 {
     XCTAssertEqual(error.code, 0);
 
+    __auto_type * params = [[MTRCommissioningParameters alloc] init];
+    params.countryCode = @("au");
+
     NSError * commissionError = nil;
-    [sController commissionNodeWithID:@(kDeviceId)
-                  commissioningParams:[[MTRCommissioningParameters alloc] init]
-                                error:&commissionError];
+    [sController commissionNodeWithID:@(kDeviceId) commissioningParams:params error:&commissionError];
     XCTAssertNil(commissionError);
 
     // Keep waiting for controller:commissioningComplete:
@@ -2350,6 +2351,25 @@
     [self waitForExpectations:@[ startupEventExpectation, expectation ] timeout:kTimeoutInSeconds];
 }
 
+- (void)test026_LocationAttribute
+{
+    __auto_type * device = GetConnectedDevice();
+    dispatch_queue_t queue = dispatch_get_main_queue();
+
+    XCTestExpectation * expectation = [self expectationWithDescription:@"read Basic Information Location attribute"];
+
+    __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device endpointID:@(0) queue:queue];
+    [cluster readAttributeLocationWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
+        XCTAssertNil(error);
+
+        // Matches what we passed in during commissioning.
+        XCTAssertEqualObjects(value, @"au");
+        [expectation fulfill];
+    }];
+
+    [self waitForExpectations:@[ expectation ] timeout:kTimeoutInSeconds];
+}
+
 - (void)test900_SubscribeAllAttributes
 {
     MTRBaseDevice * device = GetConnectedDevice();