Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/IoTHub.Portal.Infrastructure/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@
global using Microsoft.Extensions.Hosting;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Options;
global using Newtonsoft.Json;
global using Newtonsoft.Json.Linq;
global using Polly;
global using Polly.Extensions.Http;
global using Prometheus;
global using Quartz;
global using Quartz.Util;
global using Metrics = Prometheus.Metrics;
global using Newtonsoft.Json;
global using Newtonsoft.Json.Linq;
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
<EmbeddedResource Include="RouterConfigFiles\CN_470_510_RP1.json" />
<EmbeddedResource Include="RouterConfigFiles\CN_470_510_RP2.json" />
<EmbeddedResource Include="RouterConfigFiles\EU_863_870.json" />
<EmbeddedResource Include="RouterConfigFiles\IN_865_867.json" />
<EmbeddedResource Include="RouterConfigFiles\US_902_928_FSB_1.json" />
<EmbeddedResource Include="RouterConfigFiles\US_902_928_FSB_2.json" />
<EmbeddedResource Include="RouterConfigFiles\US_902_928_FSB_3.json" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void UpdateTwin(Twin twin, ConcentratorDto item)
ArgumentNullException.ThrowIfNull(twin, nameof(twin));
ArgumentNullException.ThrowIfNull(item, nameof(item));

DeviceHelper.SetTagValue(twin, nameof(item.DeviceName), item.DeviceName?.Trim());
DeviceHelper.SetTagValue(twin, nameof(item.DeviceName), item.DeviceName.Trim());
DeviceHelper.SetTagValue(twin, nameof(item.LoraRegion), item.LoraRegion);
DeviceHelper.SetTagValue(twin, nameof(item.DeviceType), item.DeviceType);

Expand Down
162 changes: 162 additions & 0 deletions src/IoTHub.Portal.Infrastructure/RouterConfigFiles/IN_865_867.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
{
"NetID": [
1
],
"JoinEui": [
[
"0000000000000000",
"FFFFFFFFFFFFFFFF"
]
],
"region": "IN865",
"hwspec": "sx1301/1",
"freq_range": [
865000000,
867000000
],
"DRs": [
[
12,
125,
0
],
[
11,
125,
0
],
[
10,
125,
0
],
[
9,
125,
0
],
[
8,
125,
0
],
[
7,
125,
0
],
[
-1,
0,
0
],
[
-1,
0,
0
],
[
-1,
0,
0
],
[
-1,
0,
0
],
[
-1,
0,
0
],
[
-1,
0,
0
],
[
6,
125,
0
],
[
5,
125,
0
]
],
"sx1301_conf":
[
{
"radio_0": {
"enable": true,
"freq": 865451250,
"tx_enable": true,
"tx_freq_min": 865000000,
"tx_freq_max": 867000000
},
"radio_1": {
"enable": true,
"freq": 866300000,
"tx_enable": false
},
"chan_multiSF_0": {
"desc": "LoRa, 125 kHz, SF 7-12, 865.0625 MHz",
"enable": true,
"radio": 0,
"if": -388750
},
"chan_multiSF_1": {
"desc": "LoRa, 125 kHz, SF 7-12, 865.2325 MHz",
"enable": true,
"radio": 0,
"if": -218750
},
"chan_multiSF_2": {
"desc": "LoRa, 125 kHz, SF 7-12, 865.4025 MHz",
"enable": true,
"radio": 0,
"if": -48750
},
"chan_multiSF_3": {
"desc": "LoRa, 125 kHz, SF 7-12, 865.5725 MHz",
"enable": true,
"radio": 0,
"if": 121250
},
"chan_multiSF_4": {
"desc": "LoRa, 125 kHz, SF 7-12, 865.84 MHz",
"enable": true,
"radio": 0,
"if": 388750
},
"chan_multiSF_5": {
"desc": "LoRa, 125 kHz, SF 7-12, 865.985 MHz",
"enable": true,
"radio": 1,
"if": -315000
},
"chan_multiSF_6": {
"desc": "LoRa, 125 kHz, SF 7-12, 866.13 MHz",
"enable": true,
"radio": 1,
"if": -170000
},
"chan_multiSF_7": {
"desc": "LoRa, 125 kHz, SF 7-12, 866.275 MHz",
"enable": true,
"radio": 1,
"if": -25000
},
"chan_FSK": {
"desc": "FSK, 125 kHz, 50kbps, 866.7 MHz",
"enable": true,
"radio": 1,
"if": 400000,
"bandwidth": 125000,
"datarate": 50000
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public LoRaWanManagementService(HttpClient httpClient)
{
var currentAssembly = Assembly.GetExecutingAssembly();

using var resourceStream = currentAssembly.GetManifestResourceStream($"{currentAssembly.GetName().Name}.RouterConfigFiles.{loRaRegion}.json");
var resourceStream = currentAssembly.GetManifestResourceStream($"{currentAssembly.GetName().Name}.RouterConfigFiles.{loRaRegion}.json");

if (resourceStream == null)
return null;
Expand All @@ -28,8 +28,8 @@ public LoRaWanManagementService(HttpClient httpClient)

public async Task<HttpResponseMessage> ExecuteLoRaDeviceMessage(string deviceId, DeviceModelCommandDto commandDto)
{
ArgumentNullException.ThrowIfNull(deviceId, nameof(deviceId));
ArgumentNullException.ThrowIfNull(commandDto, nameof(commandDto));
ArgumentNullException.ThrowIfNull(deviceId);
ArgumentNullException.ThrowIfNull(commandDto);

// Convert the hex frame to a byte array
var hexFrame = Enumerable.Range(0, commandDto.Frame.Length / 2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public ActionResult<IEnumerable<FrequencyPlan>> GetFrequencyPlans()
new FrequencyPlan { FrequencyPlanID = "AS_923_925_2", Name = "Asia 923-925 MHz, Group 2"},
new FrequencyPlan { FrequencyPlanID = "AS_923_925_3", Name = "Asia 923-925 MHz, Group 3"},
new FrequencyPlan { FrequencyPlanID = "EU_863_870", Name = "Europe 863-870 MHz"},
new FrequencyPlan { FrequencyPlanID = "IN_865_867", Name = "India 865-867 MHz"},
new FrequencyPlan { FrequencyPlanID = "CN_470_510_RP1", Name = "China 470-510 MHz, RP 1"},
new FrequencyPlan { FrequencyPlanID = "CN_470_510_RP2", Name = "China 470-510 MHz, RP 2"},
new FrequencyPlan { FrequencyPlanID = "US_902_928_FSB_1", Name = "United States 902-928 MHz, FSB 1"},
Expand Down
82 changes: 66 additions & 16 deletions src/IoTHub.Portal.Shared/Models/v1.0/LoRaWAN/Channel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,101 @@

namespace IoTHub.Portal.Models.v10.LoRaWAN
{
using JsonIgnoreAttribute = System.Text.Json.Serialization.JsonIgnoreAttribute;

/// <summary>
/// LoRaWAN Concentrator Channel configuration.
/// Covers all SX1301_conf entry types: radio_*, chan_multiSF_*, chan_Lora_std, and chan_FSK.
/// Fields absent in a given entry type deserialize as null and are omitted on re-serialization.
/// </summary>
public class Channel
{
/// <summary>
/// Human-readable description of the channel.
/// </summary>
[JsonPropertyName("desc")]
[JsonProperty("desc", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string Desc { get; set; }

/// <summary>
/// A value indicating whether the channel is enabled.
/// </summary>
[JsonPropertyName("enable")]
[JsonProperty("enable")]
[JsonProperty("enable", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? Enable { get; set; }

/// <summary>
/// The frequency.
/// The centre frequency (Hz). Present on radio_* entries only.
/// </summary>
[JsonPropertyName("freq")]
[JsonProperty("freq")]
public int Freq { get; set; }
[JsonProperty("freq", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Freq { get; set; }

/// <summary>
/// Whether TX is enabled on this radio. Present on radio_* entries only.
/// </summary>
[JsonPropertyName("tx_enable")]
[JsonProperty("tx_enable", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? TxEnable { get; set; }

/// <summary>
/// Minimum TX frequency (Hz). Present on radio_* entries only.
/// </summary>
[JsonPropertyName("tx_freq_min")]
[JsonProperty("tx_freq_min", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? TxFreqMin { get; set; }

/// <summary>
/// Maximum TX frequency (Hz). Present on radio_* entries only.
/// </summary>
[JsonPropertyName("tx_freq_max")]
[JsonProperty("tx_freq_max", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? TxFreqMax { get; set; }

/// <summary>
/// The radio.
/// The radio index (0 or 1). Present on chan_* entries only.
/// </summary>
[JsonPropertyName("radio")]
[JsonProperty("radio")]
public int Radio { get; set; }
[JsonProperty("radio", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Radio { get; set; }

/// <summary>
/// The interface.
/// The IF frequency offset (Hz). Present on chan_* entries only.
/// </summary>
[JsonPropertyName("if")]
[JsonProperty("if")]
public int If { get; set; }
[JsonProperty("if", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? If { get; set; }

/// <summary>
/// The bandwidth.
/// The bandwidth (Hz). Present on chan_Lora_std and chan_FSK entries.
/// </summary>
[JsonPropertyName("bandwidth")]
[JsonProperty("bandwidth")]
public int Bandwidth { get; set; }
[JsonProperty("bandwidth", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Bandwidth { get; set; }

/// <summary>
/// The FSK data rate (bps). Present on chan_FSK entries only.
/// </summary>
[JsonPropertyName("datarate")]
[JsonProperty("datarate", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Datarate { get; set; }

/// <summary>
/// The spread factor.
/// The spreading factor. Present on chan_Lora_std entries only.
/// </summary>
[JsonPropertyName("spread_factor")]
[JsonProperty("spread_factor")]
public int SpreadFactor { get; set; }
[JsonProperty("spread_factor", NullValueHandling = NullValueHandling.Ignore)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? SpreadFactor { get; set; }
}
}
Loading