3 * Copyright (c) 2020 Project CHIP Authors
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 #include <arpa/inet.h>
23 #include <mdns/Advertiser.h>
24 #include <platform/CHIPDeviceLayer.h>
25 #include <support/CHIPArgParser.hpp>
26 #include <support/CHIPMem.h>
32 enum class AdvertisingMode
41 bool enableIpV4 = false;
42 AdvertisingMode advertisingMode = AdvertisingMode::kCommisioning;
44 // commisioning/commisionable params
45 uint8_t shortDiscriminator = 52;
46 uint16_t longDiscriminator = 840;
47 Optional<uint16_t> vendorId;
48 Optional<uint16_t> productId;
50 // commisionable params
51 Optional<const char *> pairingInstr;
52 Optional<uint8_t> pairingHint;
55 uint64_t fabricId = 12345;
56 uint64_t nodeId = 6789;
60 using namespace chip::ArgParser;
62 constexpr uint16_t kOptionEnableIpV4 = '4';
63 constexpr uint16_t kOptionAdvertisingMode = 'm';
65 constexpr uint16_t kOptionCommisioningShordDiscriminator = 's';
66 constexpr uint16_t kOptionCommisioningLongDiscriminaotr = 'l';
67 constexpr uint16_t kOptionCommisioningVendorId = 0x100; // v is used by 'version'
68 constexpr uint16_t kOptionCommisioningProductId = 'p';
69 constexpr uint16_t kOptionCommisioningPairingInstr = 0x200; // Just use the long format
70 constexpr uint16_t kOptionCommisioningPairingHint = 0x300;
72 constexpr uint16_t kOptionOperationalFabricId = 'f';
73 constexpr uint16_t kOptionOperationalNodeId = 'n';
75 bool HandleOptions(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue)
79 case kOptionEnableIpV4:
80 gOptions.enableIpV4 = true;
82 case kOptionAdvertisingMode:
83 if (strcmp(aValue, "operational") == 0)
85 gOptions.advertisingMode = AdvertisingMode::kOperational;
87 else if (strcmp(aValue, "commisioning") == 0)
89 gOptions.advertisingMode = AdvertisingMode::kCommisioning;
91 else if (strcmp(aValue, "commisionable") == 0)
93 gOptions.advertisingMode = AdvertisingMode::kCommisionable;
97 PrintArgError("%s: Invalid advertising mode %s\n", aProgram, aValue);
102 case kOptionCommisioningShordDiscriminator:
103 gOptions.shortDiscriminator = static_cast<uint8_t>(atoi(aValue));
105 case kOptionCommisioningLongDiscriminaotr:
106 gOptions.longDiscriminator = static_cast<uint16_t>(atoi(aValue));
108 case kOptionCommisioningVendorId:
109 gOptions.vendorId = Optional<uint16_t>::Value(static_cast<uint16_t>(atoi(aValue)));
111 case kOptionCommisioningProductId:
112 gOptions.productId = Optional<uint16_t>::Value(static_cast<uint16_t>(atoi(aValue)));
114 case kOptionCommisioningPairingInstr:
115 gOptions.pairingInstr = Optional<const char *>::Value(static_cast<const char *>(aValue));
117 case kOptionCommisioningPairingHint:
118 gOptions.pairingHint = Optional<uint8_t>::Value(static_cast<uint8_t>(atoi(aValue)));
120 case kOptionOperationalFabricId:
121 gOptions.fabricId = atoll(aValue);
123 case kOptionOperationalNodeId:
124 gOptions.nodeId = atoll(aValue);
127 PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName);
132 OptionDef cmdLineOptionsDef[] = {
133 #if INET_CONFIG_ENABLE_IPV4
134 { "enable-ip-v4", kNoArgument, kOptionEnableIpV4 },
136 { "advertising-mode", kArgumentRequired, kOptionAdvertisingMode },
138 { "short-discriminator", kArgumentRequired, kOptionCommisioningShordDiscriminator },
139 { "long-discriminator", kArgumentRequired, kOptionCommisioningLongDiscriminaotr },
140 { "vendor-id", kArgumentRequired, kOptionCommisioningVendorId },
141 { "product-id", kArgumentRequired, kOptionCommisioningProductId },
142 { "pairing-instruction", kArgumentRequired, kOptionCommisioningPairingInstr },
143 { "pairing-hint", kArgumentRequired, kOptionCommisioningPairingHint },
145 { "fabrid-id", kArgumentRequired, kOptionOperationalFabricId },
146 { "node-id", kArgumentRequired, kOptionOperationalNodeId },
150 OptionSet cmdLineOptions = { HandleOptions, cmdLineOptionsDef, "PROGRAM OPTIONS",
151 #if INET_CONFIG_ENABLE_IPV4
154 " enable listening on IPv4\n"
157 " --advertising-mode <mode>\n"
158 " Advertise in this mode (operational or commisioning or commisionable).\n"
159 " --short-discriminator <value>\n"
161 " Commisioning/commisionable short discriminator.\n"
162 " --long-discriminator <value>\n"
164 " Commisioning/commisionable long discriminator.\n"
165 " --vendor-id <value>\n"
166 " Commisioning/commisionable vendor id.\n"
167 " --product-id <value>\n"
169 " Commisioning/commisionable product id.\n"
170 " --pairing-instruction <value>\n"
171 " Commisionable pairing instruction.\n"
172 " --pairing-hint <value>\n"
173 " Commisionable pairing hint.\n"
174 " --fabrid-id <value>\n"
176 " Operational fabric id.\n"
177 " --node-id <value>\n"
179 " Operational node id.\n"
182 HelpOptions helpOptions("advertiser", "Usage: advertiser [options]", "1.0");
184 OptionSet * allOptions[] = { &cmdLineOptions, &helpOptions, nullptr };
188 int main(int argc, char ** args)
190 if (Platform::MemoryInit() != CHIP_NO_ERROR)
192 fprintf(stderr, "FAILED to initialize memory\n");
196 if (DeviceLayer::PlatformMgr().InitChipStack() != CHIP_NO_ERROR)
198 fprintf(stderr, "FAILED to initialize chip stack\n");
202 if (!chip::ArgParser::ParseArgs(args[0], argc, args, allOptions))
207 if (chip::Mdns::ServiceAdvertiser::Instance().Start(&DeviceLayer::InetLayer, Mdns::kMdnsPort) != CHIP_NO_ERROR)
209 fprintf(stderr, "FAILED to start MDNS advertisement\n");
215 if (gOptions.advertisingMode == AdvertisingMode::kCommisioning)
217 err = chip::Mdns::ServiceAdvertiser::Instance().Advertise(chip::Mdns::CommissionAdvertisingParameters()
218 .EnableIpV4(gOptions.enableIpV4)
220 .SetShortDiscriminator(gOptions.shortDiscriminator)
221 .SetLongDiscrimininator(gOptions.longDiscriminator)
222 .SetVendorId(gOptions.vendorId)
223 .SetProductId(gOptions.productId));
225 else if (gOptions.advertisingMode == AdvertisingMode::kOperational)
227 err = chip::Mdns::ServiceAdvertiser::Instance().Advertise(chip::Mdns::OperationalAdvertisingParameters()
228 .EnableIpV4(gOptions.enableIpV4)
230 .SetFabricId(gOptions.fabricId)
231 .SetNodeId(gOptions.nodeId));
233 else if (gOptions.advertisingMode == AdvertisingMode::kCommisionable)
235 err = chip::Mdns::ServiceAdvertiser::Instance().Advertise(
236 chip::Mdns::CommissionAdvertisingParameters()
237 .EnableIpV4(gOptions.enableIpV4)
239 .SetShortDiscriminator(gOptions.shortDiscriminator)
240 .SetLongDiscrimininator(gOptions.longDiscriminator)
241 .SetVendorId(gOptions.vendorId)
242 .SetProductId(gOptions.productId)
243 .SetPairingInstr(gOptions.pairingInstr)
244 .SetPairingHint(gOptions.pairingHint)
245 .SetCommissionAdvertiseMode(chip::Mdns::CommssionAdvertiseMode::kCommissionable));
249 fprintf(stderr, "FAILED to determine advertising type.\n");
253 if (err != CHIP_NO_ERROR)
255 fprintf(stderr, "FAILED to setup advertisement parameters\n");
259 DeviceLayer::PlatformMgr().RunEventLoop();