Mute and Other Signals

On the Mute page of the Integrator's Guide we discuss some of the scenarios related to muting and unmuting Jabra devices. On this page we provide more detail about the signals involved in controlling and responding to mute requests. The signals functionality is also used for other device behaviour. The general behaviour is similar for all cases.

Reacting to device signals

Jabra devices send signals notifying you when something happens in the device. This could be:

  • the user expressing an intent to do something by interacting with the device. This could be pressing a button or raising the boom arm.
  • acknowledgement to a request (e.g. a SignalType.HOOK_SWITCH signal after your softphone starts a call successfully).
  • an error condition (e.g. headset out of range from the base station).

Reacting to user signals

See Code Sample

When the user interacts with the device, for example by pressing a button, a signal is sent back to the library and then your app. Reacting to a user signal involves multiple steps:

  1. Receiving the signal.
  2. Interpreting if the signal was an indication of user intent or an acknowledgement of a state change request from the PC. This usually depends on the internal state of your softphone. See the section Signals must be seen in context to the current operational state, below, for more details.
  3. Determining what the user interaction was.
  4. Reacting to the user interaction. Note that a user signal should trigger a reaction. See the section Expected signals must trigger a reaction, below, for more details.

[Note] Different signals report different values, i.e. either an absolute or a relative value. See the API documentation for more info.

sequenceDiagram
participant a as App
participant b as Jabra library
participant c as Jabra device
Note right of c: user triggers signal from device
c->>b: reports a new signal
b->>a: device.deviceSignals emits
Note over a: determine signal is a button
Note over a: determine the user intent
opt Accept call button
Note over a: determine button value
a ->> b: offHook(true | false)
b ->> c: #20
Note right of c: start or end call
end
opt Mute button
Note over a: determine button value
a ->> b: mute(true) or mute(false)
b ->> c: #20
Note right of c: mute or unmute
end

Signals are emitted only in specific cases

The library will emit signals that are sent from a device only in the following cases:

  • You have the call lock for the device (e.g. when in an active call). This will report any signal related to call control.

  • Your softphone does not have a call lock but is selected as the "Preferred Softphone" option in Jabra Direct. In this scenario, only SignalType.HOOK_SWITCH and SignalType.REDIAL signals will be reported to your softphone. The signal might come either from the user interacting with a device or from another softphone utilizing the device. If you can acquire a call lock for the device, it is the former case, and you should react on the user's intended action. See the section Expected signals must trigger a reaction, below for more details. If you can't acquire a call lock, it is the latter case - the signal is probably intended for another softphone, and you should ignore it.

Signals must be seen in context to the current operational state

It is important to understand that you do not need to react to every signal received by the device; signals that are 'out of context' from the situation at hand should be ignored.

Signals are sent to all applications that connect to the headset. Your softphone application should therefore only react to signals that you are expecting, ignoring those that do not fit into the context of the current operational state of the softphone.

Here is an example for clarification:

If your softphone has an incoming call and executes a headset's ring command, then the expected signal from the headset is an acceptance, a rejection, or simply a ‘no answer’. Here, either of the three is an expected return signal. However, if your softphone does not have an incoming call, nor has it executed a ring command, then it should not react to any ‘hook-switch’ signal from the headset.

Situations with ‘out of context’ signals can happen for various reasons, for instance when other softphones are interacting with the headset. You are strongly advised against reacting to unexpected SignalType.HOOK_SWITCH signal events. Doing so is likely to cause out-of-sync issues between the device and the software. This behaviour is explained in more detail in the section Reacting to HOOKSWITCH_, below.

Expected signals must trigger a reaction

Once you have taken context into account (see the previous section for more details) and ensured that a signal is targeting your softphone, it is important to react to that signal.

When the device sends a signal, e.g. user presses the mute button, the signal does not itself change the state on your softphone. The device just passes the signal and it is then expected that the software reacts to it. However, the state on the device is already changed. For this reason, it is important that your solution handles each signal. Otherwise, the state in your softphone and on the device could become out of sync.

To illustrate with an example, receiving a SignalType.PHONE_MUTE signal means the user either muted or unmuted the microphone. For example, this could be done by physically manipulating the boom arm on a headset. If your solution does not react to this signal and execute ICallControl.mute with an appropriate parameter, the device will interpret that as refusal to acknowledge the change, and will internally revert to the previous state. This causes an out-of-sync, because the microphone could be in a physical state where it's muted (e.g. boom arm is raised), but it thinks it's unmuted. A subsequent user action to mute or unmute will not trigger a new signal, and your application will not know the "true" physical state of the microphone.

[Note] In this entire section, we assume you are in a state where your softphone expects said signal. As noted in the section Signals must be seen in context to the current operational state, earlier, context matters and you should only react to signals when you are sure they are targeting your softphone.

For the given example of muting the microphone, the sequence diagram is as follows:

sequenceDiagram
participant a as App
participant b as Jabra library
participant c as Jabra device
Note right of c: User mutes their microphone
c ->> b: reports a new signal
b ->> a: device.deviceSignals emits
Note over a: Determine it is user signal
Note over a: Determine it is the mute button
Note over a: Determine new mute state
opt new state is muted
a ->> b: device.mute(true);
b ->> c: #20
Note right of c: The device mutes
Note over a: Update UI to reflect new state
end
opt new state is unmuted
a ->> b: device.mute(false);
b ->> c: #20
Note right of c: The device unmutes
Note over a: Update UI to reflect new state
end
opt Ignore mute button
Note over a, c: Mute state no longer in sync
end

Reacting to HOOK_SWITCH

An important note about the SignalType.HOOK_SWITCH signal. The device sends this signal in several scenarios:

  • as an acknowledgement of a successful ICallControl.offHook request made by your softphone (see the section Signals are emitted only in specific cases, above),

  • when the user is trying to accept an incoming call by interacting with the device, or

  • when the user is trying to start a new outgoing call by interacting with the device.

For that reason, it is important that you understand the context of the SignalType.HOOK_SWITCH signal:

  • If your softphone just started a new call, you will receive an acknowledgement, and should do nothing more.

[Note] If you don't get an 'acknowledge' response signal within a reasonable time limit, that means the command was rejected, the device didn't change its state, and the its inactivity in regards to responding should be interpreted as a 'NACK' (not acknowledged). For example, if you started a new call and didn't receive an acknowledgement, either the device refused to start a new call, or you didn't inform the device that a new call has started (via ICallControl.offHook(true)). This behaviour can be easily observed by executing ICallControl.offHook(true) twice, without any other commands in between. In that case, the second call will not be acknowledged, as the state of the device will not change.

  • If your softphone has an incoming call and asked the device to start ringing, receiving this signal means the user accepted the call by indicating that they wished do so on the device.

  • If your softphone is idling, this signal either means another softphone on the computer is trying to start a call, or that the user is trying to start an outgoing call on your softphone. As noted earlier in the section Signals are emitted only in specific cases, whether you should act on this case depends on whether your softphone can acquire a call lock for the device.

Next Steps

  • Jump to the Mute part of the Integrator's guide.