Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heartbeat Messages #617

Closed
ahmadshoh-orc opened this issue Jul 23, 2024 · 1 comment
Closed

Heartbeat Messages #617

ahmadshoh-orc opened this issue Jul 23, 2024 · 1 comment
Labels
question Further information is requested

Comments

@ahmadshoh-orc
Copy link

ahmadshoh-orc commented Jul 23, 2024

Version

4.2.0 (latest)

Ask the question

I'm working on implementing Heartbeat logic in my application, but I'm encountering some issues with catching and processing incoming HeartbeatMessages.

Here's what I’ve done so far:

  1. I sent a ConfigHeartbeatPublicationSet to the hardware and received a ConfigHeartbeatPublicationStatus indicating success.

  2. However, when I try to retrieve the heartbeat data by sending a ConfigHeartbeatPublicationGet, I encounter a timeout.

  3. In the logs, I see that Heartbeat Messages are being received every 15 seconds as expected, with entries like:

    Heartbeat Message (initial TTL: 8, received TTL: 7, hops: 2, features: [relay, proxy]) received from 000E
    

Despite this, I’m unable to catch these HeartbeatMessages in my application and perform the desired logic.

What I Need Help With:

  • How can I correctly capture and process these HeartbeatMessages?
  • Are there any specific configurations or code implementations required to handle these messages effectively?

Any guidance or examples on how to integrate this functionality would be greatly appreciated!

Relevant log output

* Configuration logs
Sending ConfigHeartbeatPublicationSet(networkKeyIndex: 0, destination: 1, countLog: 255, periodLog: 4, ttl: 8, features: [relay, proxy, friend, lowPower]) to: 0016
ConfigHeartbeatPublicationStatus(status: Success, networkKeyIndex: 0, destination: 1, countLog: 255, periodLog: 4, ttl: 8, features: [relay, proxy, friend, lowPower]) received from: 0016

* Trying to get HeartbeatPublicationStatus:
Sending ConfigHeartbeatPublicationGet() from: PrimaryElement (0x0001), to: 0016

Response to Access PDU (opcode: 0x8038, parameters: 0x) not received (timeout)
ConfigHeartbeatPublicationGet() sent from: 0001, to: 0016 timed out
Cancelling messages with op code: 32824, sent from: 0001 to: 0016
@ahmadshoh-orc ahmadshoh-orc added the question Further information is requested label Jul 23, 2024
@philips77
Copy link
Member

philips77 commented Jul 24, 2024

Hello,
You need to subscribe the local node to heartbeat messages by sending ConfigHeartbeatSubscriptionSet message:

func setSubscription() {
guard let sourceIndexPath = selectedSourceIndexPath,
let destinationIndexPath = selectedDestinationIndexPath,
let node = self.node else {
return
}
let sourceAddress = nodes[sourceIndexPath.row].primaryUnicastAddress
let destinationAddress =
destinationIndexPath.isDestinationSection ?
node.primaryUnicastAddress :
destinationIndexPath.isGroupsSection && !groups.isEmpty ?
groups[destinationIndexPath.row].address.address :
Group.specialGroups[destinationIndexPath.row].address.address
let periodLog = self.periodLog
start("Setting Heartbeat Subscription...") {
let message: AcknowledgedConfigMessage =
ConfigHeartbeatSubscriptionSet(startProcessingHeartbeatMessagesFor: periodLog,
secondsSentFrom: sourceAddress,
to: destinationAddress)!
return try MeshNetworkManager.instance.send(message, to: node)
}
}

When a heartbeat message is received it is being processed here:

/// Handles received Heartbeat message. If the local Node has active subscription
/// matching received Heartbeat, the count value will be incremented.
///
/// - parameter heartbeat: Received Heartbeat message.
func handle(heartbeat: HeartbeatMessage) {
guard let localNode = meshNetwork.localProvisioner?.node,
let heartbeatSubscription = localNode.heartbeatSubscription else {
return
}
heartbeatSubscription.updateIfMatches(heartbeat)
}

and the count is incremented only when the subscription is active.

To get the current count, send ConfigHeartbeatSubscriptionGet message to the local node, which will return the status message:

case is ConfigHeartbeatSubscriptionGet:
return ConfigHeartbeatSubscriptionStatus(localNode.heartbeatSubscription)

Mind, that the implementation is based on the spec, so currently it's not possible to get a callback for every heartbeat message or obtain the exact count (log value is sent instead). It is also not possible to subscribe to more than one source at a time. There are open tasks #470 and #471 which would improve it by adding designated callbacks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants