Skip to content

Commit dc859d1

Browse files
authored
Bug fix and code refactoring (#35)
* Refactor services and add GrpcDeviceCapabilities class Refactored AntChannelService, AntRadioService, GrpcAntResponse, and GrpcDeviceCapabilities to new implementations under AntGrpcShared.ClientServices namespace. Updated AntGrpcShared.csproj with new package and project references. Added necessary using directives in MauiProgram.cs and HomePageViewModel.cs. Introduced GrpcDeviceCapabilities class to represent ANT radio device capabilities. * Update proto messages, add GrpcChannelOptions support Updated AntGrpcShared.csproj to change AssemblyVersion to 2.1.0.0. Enhanced XML documentation in AntChannelService.cs and GrpcDeviceCapabilities.cs. Added readonly field _grpcChannelOptions in AntRadioService.cs and updated constructor to accept optional GrpcChannelOptions. Updated ant_channel.proto with new message types and fields including SubscribeRequest, ChannelResponseUpdate, ExtDataRequest, and MessagingCodeReply. Expanded MessagingReturnCode enum. Updated ant_radio.proto with new message types and fields including InitScanModeReply, GetChannelRequest, ReadUserNvmRequest, and WriteRawMessageToDeviceRequest. * Issue #34 Update AssemblyVersion and ensure consistent decimal format Updated AssemblyVersion in AntPlus.csproj from 4.0.0.0 to 4.1.0.0. Introduced NumberFormatInfo in ProductInfoPage constructor to ensure consistent decimal separator when parsing software revision numbers. * Fix culture-specific parsing issue in ProductInfoPage Updated AssemblyVersion in AntPlus.csproj to 4.0.1.0. Revised PackageReleaseNotes to include bug fix details. Modified ProductInfoPage constructor to use NumberFormatInfo.InvariantInfo for culture-invariant parsing. * Completed gRPC classes for server and client. * Update documentation and fix typos Updated titles and descriptions in various .aml files to reflect new project details and functionalities. Removed detailed gRPC service descriptions and replaced them with a link to a new topic. Added new sections for specific classes in `AntGrpcShared.aml`. Corrected typos in `AntGrpcService.aml` and `v4.0.0.0.aml`. Updated `ContentLayout.content` and `Documentation.shfbproj` for version 4.0.1.0. Renamed a method in `AntChannelService.cs` and `AntRadioService.cs`.
1 parent 91485d8 commit dc859d1

24 files changed

+1203
-376
lines changed

AntPlus/AntPlus.csproj

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<AssemblyVersion>4.0.0.0</AssemblyVersion>
4+
<AssemblyVersion>4.0.1.0</AssemblyVersion>
55
<TargetFramework>netstandard2.0</TargetFramework>
66
<GenerateDocumentationFile>True</GenerateDocumentationFile>
77
<RootNamespace>SmallEarthTech.$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
@@ -24,10 +24,7 @@
2424
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
2525
<PackageIcon>PackageLogo.png</PackageIcon>
2626
<PackageReadmeFile>readme.md</PackageReadmeFile>
27-
<PackageReleaseNotes>1. All device profiles employ the CommunityToolkit.Mvvm. This makes it much easier tor the device profiles to participate as view models.
28-
2. ChannelCount was added to AntDevice and device profiles to enable scaling the device timeouts based on the number of missed messags.
29-
3. Device timeouts can be disabled by setting the timeout argument to -1 (Timeout.Infinite).
30-
4. Added TimeoutOptions class to provide support to ANT+ hosting extensions.</PackageReleaseNotes>
27+
<PackageReleaseNotes>Bug fix: Parsing ProductInfoPage failed in cultures that use "decimal comma" for decimal separator. Added culture invariant NumberFormatInfo with NumberDecimalSeparator = ".". Issue #34.</PackageReleaseNotes>
3128
</PropertyGroup>
3229

3330
<PropertyGroup>

AntPlus/CommonDataPages.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using CommunityToolkit.Mvvm.ComponentModel;
22
using Microsoft.Extensions.Logging;
33
using System;
4+
using System.Globalization;
45
using System.Linq;
56

67
namespace SmallEarthTech.AntPlus
@@ -203,15 +204,16 @@ public readonly struct ProductInfoPage
203204

204205
internal ProductInfoPage(byte[] dataPage)
205206
{
207+
// SW revision is in the form of X.Y regardless of current culture
206208
if (dataPage[2] != 0xFF)
207209
{
208210
// supplemental SW revision is valid
209-
SoftwareRevision = Version.Parse(((dataPage[3] * 100.0 + dataPage[2]) / 1000.0).ToString("N3"));
211+
SoftwareRevision = Version.Parse(((dataPage[3] * 100.0 + dataPage[2]) / 1000.0).ToString("N3", NumberFormatInfo.InvariantInfo));
210212
}
211213
else
212214
{
213215
// only main SW revision is present
214-
SoftwareRevision = Version.Parse((dataPage[3] / 10.0).ToString("N3"));
216+
SoftwareRevision = Version.Parse((dataPage[3] / 10.0).ToString("N3", NumberFormatInfo.InvariantInfo));
215217
}
216218
SerialNumber = BitConverter.ToUInt32(dataPage, 4);
217219
}

Documentation/Content/Examples/ExamplesOverview.aml

+2-74
Original file line numberDiff line numberDiff line change
@@ -92,92 +92,20 @@
9292
</sections>
9393
</section>
9494
<section address="Section4">
95-
<title>The MAUI Example Projects</title>
95+
<title>.NET MAUI/gRPC Example Projects</title>
9696
<content>
9797
<para>
9898
This group of examples is comprised of four projects. AntGrpcShared is a class library providing a gRPC client/server to be consumed by the other
9999
projects. AntGrpcService is a Windows service that provides services to connect to and communicate with an ANT USB stick.
100100
The MauiAntClientApp is a .NET MAUI project and gRPC client that is used to demonstrate Windows/Android applications that work with the
101101
remote server application on a local subnet. <legacyBold>I have not tested the other platforms supported by .NET MAUI.</legacyBold>
102102
</para>
103-
<alert class="note" title="About gRPC">
104-
<para>
105-
gRPC is a Google defined protocol for remote procedure calls. It is the recommended RPC to use instead of WCF. Do not
106-
confuse <legacyBold>gRPC channels</legacyBold> with <legacyBold>ANT radio channels</legacyBold>. gRPC is a
107-
network protocol, ANT radio channels are a Dynastream/Garmin protocol for ANT radios.
108-
</para>
109-
</alert>
110103
<para>
111-
The intent of AntGrpcService is to make the ANT USB stick accessible not only to client applications running on the local
112-
host but mobile device emulators and mobile devices connected to the network the service is running on.
113-
</para>
114-
<para>
115-
AntGrpcShared is the glue that facilitates communication between clients and the service. The benefit of using
116-
gRPC is that multiple clients can run simultaneously, both on the local PC and over the network.
104+
See the <link xlink:href="3ab7deee-1a9a-4d77-9fc4-14343f3bd1ca">MAUI-gRPC Examples</link> topic for more information.
117105
</para>
118106
</content>
119107
<!-- If a section contains a sections element, its content creates
120108
sub-sections. These are not collapsible. -->
121-
<sections>
122-
<section address="SubSection1">
123-
<title>AntGrpcShared</title>
124-
<content>
125-
<para>
126-
This class library is configured as a gRPC client/server library. The .proto files define the messages and data exchanged
127-
between client and server implementations.
128-
</para>
129-
</content>
130-
</section>
131-
<section address="SubSection2">
132-
<title>AntGrpcService</title>
133-
<content>
134-
<para>
135-
The server is a Windows service that runs on the host PC that has an ANT USB stick connected to it. Three services are
136-
provided.
137-
</para>
138-
<para>
139-
The DiscoveryService replies to client messages over a UDP multicast port on the local subnet. This allows clients to obtain
140-
the URI of the server and connect to the gRPC channel. Think of it as a poor man's service discovery protocol. No authentication
141-
or validation is performed.
142-
</para>
143-
<para>
144-
The AntRadioService provides methods to get information about the connected ANT USB stick, initialize for continuous scan mode,
145-
and get channels to communicate with ANT devices via the AntChannelService.
146-
</para>
147-
<para>
148-
The AntChannelService has a method to subscribe to a gRPC stream of ANT messages when the ANT USB stick has been initialized
149-
for continuous scan mode. The remaining gRPC/ANT radio channels are used to send extended acknowledged messages to individual
150-
ANT devices.
151-
</para>
152-
<para>
153-
<legacyBold>The service can be debugged!</legacyBold> Make sure the service is not installed or disable it in the
154-
service controller (<application>services.msc</application>). Select the Debug solution configuration and launch it
155-
from Visual Studio. A console window will open. Logging output is displayed in the console window and breakpoints
156-
can be set.
157-
</para>
158-
</content>
159-
</section>
160-
<section address="SubSection3">
161-
<title>MauiAntClientApp</title>
162-
<content>
163-
<para>
164-
The client app is the consumer of the client services provided by AntGrpcShared project. The server URI is first obtained via
165-
a UDP multicast message, a gRPC connection to the server is established, and then requests to initialize and communicate with the
166-
remote ANT USB stick are invoked.
167-
</para>
168-
</content>
169-
</section>
170-
<section address="SubSection4">
171-
<title>AntGrpcServicePackage</title>
172-
<content>
173-
<para>
174-
The AntGrpcServicePackage installs the AntGrpcService on the local Windows PC and creates a firewall exception allowing network
175-
traffic between the service and any clients on the network. Wix is used to create the MSI file. You must install the
176-
Wix toolset to build this project.
177-
</para>
178-
</content>
179-
</section>
180-
</sections>
181109
</section>
182110

183111
<relatedTopics>

Documentation/Content/Examples/MAUI-gRPC/AntGrpcService.aml

+1-7
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
<para>
2121
This example creates an AntGrpcService that may run as a console application or installed and run as a Windows service.
22-
You can debug and set breakpoints if this ample is run as a console application.
22+
You can debug and set breakpoints if this example is run as a console application.
2323
</para>
2424
<alert class="security note">
2525
<para>
@@ -34,12 +34,6 @@
3434
If using <autoOutline />, add an address attribute to identify it
3535
and specify a title so that it can be jumped to with a hyperlink. -->
3636
<section address="Section1">
37-
<title>Services</title>
38-
<content>
39-
<!-- Uncomment this to create a sub-section outline
40-
<autoOutline /> -->
41-
<para>There following three services are implemented.</para>
42-
</content>
4337
<!-- If a section contains a sections element, its content creates
4438
sub-sections. These are not collapsible. -->
4539
<sections>

Documentation/Content/Examples/MAUI-gRPC/AntGrpcShared.aml

+34-10
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,58 @@
1717
zero (0) to limit it to top-level sections only. -->
1818
<!-- <autoOutline /> -->
1919

20-
<para>
20+
<para>
2121
This project generates the server and client gRPC messaging protocols for other projects to use. Two protocol files are
2222
defined - ant_radio.proto and ant_channel.proto. These are compiled by the protobuf compiler into C# classes, yielding
23-
source files for clients and servers, which in turn are compiled into the class library.
23+
source files for clients and servers, which in turn are compiled into the AntGrpcShared class library.
2424
</para>
2525
<alert class="note" title="About gRPC">
2626
<para>
2727
gRPC is a Google defined protocol for remote procedure calls. It is the recommended RPC to use.
2828
</para>
2929
</alert>
3030
<para>
31-
Servers/services will derive from gRPCAntRadio.gRPCAntRadioBase and gRPCAntChannel.gRPCAntChannelBase.
31+
Servers/services will derive from gRPCAntRadio.gRPCAntRadioBase and gRPCAntChannel.gRPCAntChannelBase. See
32+
the AntGrpcService project for an example of how to implement these services.
3233
</para>
3334
<para>
34-
Clients will reference gRPCAntRadio.gRPCAntRadioClient and gRPCAntChannel.gRPCAntChannelClient.
35+
Clients will use the AntRadioService and AntChannelService classes to communicate with the server. These classes
36+
are defined in the <application>AntGrpcShared.ClientServices</application> namespace. These classes greatly simplify integration of ANT gRPC
37+
into client-side applications. Reference this project or copy the assembly into your client application to use these classes.
3538
</para>
36-
<alert class="note" title="Implementation">
37-
<para>
38-
This is a minimal implementation that supports the examples. It will be expanded upon in the near future.
39-
</para>
40-
</alert>
4139
</introduction>
4240

4341
<!-- Add one or more top-level section elements. These are collapsible.
4442
If using <autoOutline />, add an address attribute to identify it
4543
and specify a title so that it can be jumped to with a hyperlink. -->
44+
<section address="S1">
45+
<title>AntRadioService Class</title>
46+
<content>
47+
<para>
48+
The AntRadioService implements IAntRadio and provides services for managing the ANT radio server. It
49+
extends IAntRadio with a method, FindAntRadioServerAsync, to find and connect to the server. It also
50+
exposes the server IP address property.
51+
</para>
52+
<para>
53+
The AntRadioService class is currently configured to use the multicast address 239.55.43.6, port 55437 for server
54+
discovery. The server must be running on the same subnet as the client for discovery to work. The gRPC
55+
channel is created using the server IP address and port number 5073. This matches the gRPC server configuration
56+
implemented in the AntGrpcService project.
57+
</para>
58+
</content>
59+
</section>
60+
<section address="S2">
61+
<title>AntChannelService Class</title>
62+
<content>
63+
<para>
64+
The AntChannelService implements IAntChannel and provides services for managing the ANT radio server
65+
channels. It extends IAntChannel with a method, HandleChannelResponseUpdates, which subscribes to and
66+
handles channel response updates.
67+
</para>
68+
</content>
69+
</section>
4670

47-
<relatedTopics>
71+
<relatedTopics>
4872
<link xlink:href="3ab7deee-1a9a-4d77-9fc4-14343f3bd1ca" />
4973
<!-- One or more of the following:
5074
- A local link

Documentation/Content/Examples/MAUI-gRPC/MauiExampleOverview.aml

+9-4
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,17 @@
3333
The intent of AntGrpcService is to make the ANT USB stick accessible not only to client applications running on the local
3434
host but mobile device emulators and mobile devices connected to the network the service is running on.
3535
</para>
36+
<para>
37+
AntGrpcShared is the glue that facilitates communication between clients and the service. The benefit of using
38+
gRPC is that multiple clients can run simultaneously, both on the local PC and over the network.
39+
</para>
3640
</introduction>
3741

3842
<!-- Add one or more top-level section elements. These are collapsible.
3943
If using <autoOutline />, add an address attribute to identify it
4044
and specify a title so that it can be jumped to with a hyperlink. -->
4145
<section address="Section1">
42-
<title>The MAUI Example Projects</title>
46+
<title>The MAUI/gRPC Example Projects</title>
4347
<content>
4448
<para>
4549
AntGrpcShared is the glue that facilitates communication between clients and the service. The benefit of using
@@ -54,16 +58,17 @@
5458
<content>
5559
<para>
5660
This class library is configured as a gRPC client/server library. The .proto files define the messages and data exchanged
57-
between client and server implementations.
61+
between client and server implementations. Additional classes are generated by the gRPC tools to facilitate the communication.
62+
AntGrpcShared.ClientServices namespace provides the client services to connect to the server.
5863
</para>
5964
</content>
6065
</section>
6166
<section address="SubSection2">
6267
<title>AntGrpcService</title>
6368
<content>
6469
<para>
65-
The server is a Windows service that runs on the host PC that has an ANT USB stick connected to it. Three services are
66-
provided.
70+
The server is a Windows service that runs on the host PC that has an ANT USB stick connected to it.
71+
The server may also run as a console application. Three services are provided - DiscoveryService, AntRadioService, and AntChannelService.
6772
</para>
6873
<para>
6974
The DiscoveryService replies to client messages over a UDP multicast port on the local subnet. This allows clients to obtain

Documentation/Content/Godot/GodotGameDev.aml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<!-- <autoOutline /> -->
1919

2020
<para>
21-
I've created a Unity example project to demonstrate integrating elements of the ANT+ class library and extensions.
21+
I've created a Godot example project to demonstrate integrating elements of the ANT+ class library and extensions.
2222
The repository is located at
2323
<externalLink>
2424
<linkText>Godot ANT gRPC.</linkText>

Documentation/Content/VersionHistory/AntPlus/AntPllusVersionHistory.aml

+5
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@
5656
<link xlink:href="44f85400-6285-4dbe-8f65-d28b68108fc1" />
5757
</para>
5858
</listItem>
59+
<listItem>
60+
<para>
61+
<link xlink:href="10a23545-666c-497d-a851-14eb7ac619e8" />
62+
</para>
63+
</listItem>
5964
</list>
6065
</content>
6166
<!-- If a section contains a sections element, its content creates

Documentation/Content/VersionHistory/AntPlus/v4.0.0.0.aml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
zero (0) to limit it to top-level sections only. -->
1818
<!-- <autoOutline /> -->
1919

20-
<para>Version 4.0.0.0 was release August 2024</para>
20+
<para>Version 4.0.0.0 was released August 2024</para>
2121
</introduction>
2222

2323
<!-- Add one or more top-level section elements. These are collapsible.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<topic id="10a23545-666c-497d-a851-14eb7ac619e8" revisionNumber="1">
3+
<developerConceptualDocument
4+
xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5"
5+
xmlns:xlink="http://www.w3.org/1999/xlink">
6+
7+
<!--
8+
<summary>
9+
<para>Optional summary abstract</para>
10+
</summary>
11+
-->
12+
13+
<introduction>
14+
<!-- Uncomment this to generate an outline of the section and sub-section
15+
titles. Specify a numeric value as the inner text to limit it to
16+
a specific number of sub-topics when creating the outline. Specify
17+
zero (0) to limit it to top-level sections only. -->
18+
<!-- <autoOutline /> -->
19+
20+
<para>Version 4.0.1.0 was released January 2025</para>
21+
</introduction>
22+
23+
<!-- Add one or more top-level section elements. These are collapsible.
24+
If using <autoOutline />, add an address attribute to identify it
25+
and specify a title so that it can be jumped to with a hyperlink. -->
26+
<section address="Section1">
27+
<content>
28+
<!-- Uncomment this to create a sub-section outline
29+
<autoOutline /> -->
30+
<para>
31+
Bug fix: Fixed issue #34 parsing the software version broadcast in common data product info page. Some
32+
cultures use a comma as the decimal separator, which caused the Version class parsing to fail.
33+
</para>
34+
</content>
35+
<!-- If a section contains a sections element, its content creates
36+
sub-sections. These are not collapsible.
37+
<sections>
38+
<section address="SubSection1">
39+
<title>Sub-section 1</title>
40+
<content>
41+
<para>Sub-section content.</para>
42+
</content>
43+
</section>
44+
<section address="SubSection2">
45+
<title>Sub-section 2</title>
46+
<content>
47+
<para>Sub-section content.</para>
48+
</content>
49+
</section>
50+
</sections> -->
51+
</section>
52+
53+
<relatedTopics>
54+
<link xlink:href="c4caecfe-e2ea-4c87-b602-75d6b57aa70b" />
55+
<!-- One or more of the following:
56+
- A local link
57+
- An external link
58+
- A code entity reference
59+
60+
<link xlink:href="Other Topic's ID"/>
61+
<link xlink:href="Other Topic's ID">Link inner text</link>
62+
63+
<externalLink>
64+
<linkText>Link text</linkText>
65+
<linkAlternateText>Optional alternate link text</linkAlternateText>
66+
<linkUri>URI</linkUri>
67+
</externalLink>
68+
69+
<codeEntityReference>API member ID</codeEntityReference>
70+
71+
Examples:
72+
73+
<link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8270" />
74+
<link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link>
75+
76+
<externalLink>
77+
<linkText>SHFB on GitHub</linkText>
78+
<linkAlternateText>Go to GitHub</linkAlternateText>
79+
<linkUri>https://GitHub.com/EWSoftware/SHFB</linkUri>
80+
</externalLink>
81+
82+
<codeEntityReference>T:TestDoc.TestClass</codeEntityReference>
83+
<codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference>
84+
<codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference>
85+
<codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference>
86+
<codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference>
87+
<codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference>
88+
<codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference>
89+
-->
90+
</relatedTopics>
91+
</developerConceptualDocument>
92+
</topic>

0 commit comments

Comments
 (0)