Snom BLF XML and Asterisk

IF you use the BLF LEDs of the function keys of Snom Phones (e.g. D345 or D745) you most probably know the the Snom Documentation for Asterisk with chan_sip. A definition for a function key then looks like:

<fkey idx="6" context="1" label="Office" perm="R">
<general type="AsteriskPresenceField"/>
<initialization>
  <state value="initial"/>
  <variable name="subscr_ext" value="10"/>
  <variable name="subscr_proxy" value="my.sip.domain"/>
  <variable name="pickup_code" value="**"/>
  <variable name="subscr_uri" value="sip:$(subscr_ext)@$(subscr_proxy)"/>
</initialization>
<subscription type="presence" to="<$(subscr_uri)>" for="$(subscr_uri)"/>
<NotifyParsingRules type="applies">
  <level1 translates_to='OK'>/presence/tuple/contact[.="$(subscr_uri)"]</level1>
</NotifyParsingRules>
<NotifyParsingRules type="state">
  <level1 translates_to="Away">/presence/pp:person/status/ep:activities/ep:away</level1>
  <level1-1 translates_to="Offline">/presence/tuple/status/basic[.="closed"]</level1-1>
  <level2 translates_to="Busy">/presence/pp:person/status/ep:activities/ep:busy</level2>
  <level2-1 translates_to="Ringing">/presence/note[.="Ringing"]</level2-1> 
  <level2-2 translates_to="Holding">/presence/note[.="On hold"]</level2-2>
  <level3 translates_to="Registered">/presence/tuple/status/basic[.="open"]</level3>
</NotifyParsingRules>
<action>
  <dial target="$(pickup_code)$(subscr_ext)" when="on press" states="Ringing"/>
  <invite target="$(pickup_code)$(subscr_ext)" when="on press" states="Ringing"/>
  <dial target="$(subscr_ext)" when="on press" states="Registered"/>
  <invite target="$(subscr_ext)" when="on press" states="Registered"/>
  <dial target="$(subscr_ext)" when="on press" states="Busy"/>
  <invite target="$(subscr_ext)" when="on press" states="Busy"/>
  <dial target="$(subscr_ext)" when="on press" states="Holding"/>
  <invite target="$(subscr_ext)" when="on press" states="Holding"/>
</action>
</fkey>

This works great with chan_sip but unfortunately chan_sip is deprecated and will be removed in Asterisk 21 which is scheduled to be released this year (2023). Sadly there is no proper documentation for Asterisk with PJSIP, so one has to trace sip event messages, read documentation here, there, and the glory details. Eventually one can resurrect the BLF funtionality with all the information gathered. What's required first is to configure Asterisk's module.conf to get the proper type of event message:

load => res_pjsip_pubsub.so
load => res_pjsip_exten_state.so
noload => res_pjsip_xpidf_body_generator.so
noload => res_pjsip_dialog_info_body_generator.so
load => res_pjsip_pidf_body_generator.so

Then the XML parsing of the phone has to be adapted to the event messages PJSIP publishes. This results in:

<fkey idx="6" context="1" label="Office" perm="R">
<general type="AsteriskPresenceField"/>
<initialization>
  <state value="initial"/>
  <variable name="subscr_ext" value="10"/>
  <variable name="subscr_proxy" value="my.sip.domain"/>
  <variable name="pickup_code" value="**"/>
  <variable name="subscr_uri" value="sip:$(subscr_ext)@$(subscr_proxy)"/>
</initialization>
<subscription type="presence" to="<$(subscr_uri)>" for="$(subscr_uri)"/>
<NotifyParsingRules type="applies">
  <level1 translates_to='OK'>/presence[@entity="$(subscr_uri)"]</level1>
</NotifyParsingRules>
<NotifyParsingRules type="state">
  <level1 translates_to="Away">/presence/note[.="Unavailable"]</level1>
  <level1-1 translates_to="Offline">/presence/tuple/status/basic[.="closed"]</level1-1>
  <level2 translates_to="Busy">/presence/dm:person/rpid:activities/rpid:on-the-phone</level2>
  <level2-1 translates_to="Ringing">/presence/note[.="Ringing"]</level2-1> 
  <level2-2 translates_to="Holding">/presence/note[.="On hold"]</level2-2>
  <level3 translates_to="Registered">/presence/tuple/status/basic[.="open"]</level3>
</NotifyParsingRules>
<action>
  <dial target="$(pickup_code)$(subscr_ext)" when="on press" states="Ringing"/>
  <invite target="$(pickup_code)$(subscr_ext)" when="on press" states="Ringing"/>
  <dial target="$(subscr_ext)" when="on press" states="Registered"/>
  <invite target="$(subscr_ext)" when="on press" states="Registered"/>
  <dial target="$(subscr_ext)" when="on press" states="Busy"/>
  <invite target="$(subscr_ext)" when="on press" states="Busy"/>
  <dial target="$(subscr_ext)" when="on press" states="Holding"/>
  <invite target="$(subscr_ext)" when="on press" states="Holding"/>
</action>
</fkey>

Now the BLF LEDs work with Asterisk and PJSIP as they did with chan_sip. I just do wonder why there is no documentation from Snom for this.