diff --git a/src/commands/common/index.ts b/src/commands/common/index.ts index 2414d099c317411af58673444880165fbc39ccc7..15a4a205673e3e1c122674873e564b8e5c26e457 100644 --- a/src/commands/common/index.ts +++ b/src/commands/common/index.ts @@ -7,6 +7,7 @@ import supported from "./supported"; import proto from "./proto"; import instances from "./instances"; import notify from "./notify"; +import notifyResp from "./notifyResp"; export default { GET: get, @@ -14,6 +15,7 @@ export default { GET_SUPPORTED_DM: supported, GET_SUPPORTED_PROTO: proto, NOTIFY: notify, + NOTIFY_RESP: notifyResp, ADD: add, DELETE: del, OPERATE: operate, diff --git a/src/commands/common/notify.ts b/src/commands/common/notify.ts index 25ac2f963cc6eb7d0422d59479771404d4980e5c..ceadbbbf52e91524920fe45baea2bfd2416563b5 100644 --- a/src/commands/common/notify.ts +++ b/src/commands/common/notify.ts @@ -10,7 +10,9 @@ const decode: DecodeFn = (msg) => { const parent = util.searchParent(msg, "subscriptionId"); if (parent) { const id = parent.subscriptionId; - const relField = Object.keys(parent).find((k) => k !== "subscriptionId"); + const relField = Object.keys(parent).find((k) => + k !== "subscriptionId" && k !== "sendResp" + ); return id && relField ? [parseInfo(relField, msg), id, null] : [null, id, null]; diff --git a/src/commands/common/notifyResp.ts b/src/commands/common/notifyResp.ts new file mode 100644 index 0000000000000000000000000000000000000000..e09f7225f5022776946d8aef0567cb9bf083fb03 --- /dev/null +++ b/src/commands/common/notifyResp.ts @@ -0,0 +1,25 @@ +import { DecodeFn, EncodeFn } from "../../types"; +import { uniq } from "../util"; + +const decode: DecodeFn = (msg) => [msg]; + +const encode: EncodeFn = ({ subscriptionId }) => ({ + lookup: "Msg", + header: { + msgId: uniq("NOTIFY_RESP@"), + msgType: "NOTIFY_RESP", + lookup: "Header", + }, + body: { + lookup: "Body", + request: { + lookup: "Request", + notifyResp: { subscriptionId }, + }, + }, +}); + +export default { + decode, + encode, +}; diff --git a/src/commands/recipes/subscribe.ts b/src/commands/recipes/subscribe.ts index 2b19d8aba22cff850c41f4a736199d6d48a918d1..412cb989dbf12661eae8360ee496fb07c3570233 100644 --- a/src/commands/recipes/subscribe.ts +++ b/src/commands/recipes/subscribe.ts @@ -3,28 +3,38 @@ import { uniq } from "../util"; const subscriptionPath = "Device.LocalAgent.Subscription."; -const make: MakeFn = (call, on): SubscribeRecipe => async (opts, callback) => { - const id = "NOTIFY@" + (opts.id || uniq()); - const refList = Array.isArray(opts.reference) ? opts.reference.join(",") : opts.reference +const make: MakeFn = + (call, on): SubscribeRecipe => + async (opts, callback) => { + const id = "NOTIFY@" + (opts.id || uniq()); + const refList = Array.isArray(opts.reference) + ? opts.reference.join(",") + : opts.reference; - const newSubPath = await call("ADD", { - path: subscriptionPath, - value: { - Enable: true, - ID: id, - NotifType: opts.notif, - NotifRetry: 'retry' in opts ? opts.retry : true, - ReferenceList: refList, - Persistent: false, - }, - }); + const newSubPath = await call("ADD", { + path: subscriptionPath, + value: { + Enable: true, + ID: id, + NotifType: opts.notif, + NotifRetry: "retry" in opts ? opts.retry : true, + ReferenceList: refList, + Persistent: false, + }, + }); - const clear = on(id, callback); - return () => { - clear(); - return call("DELETE", { paths: newSubPath }) - } -}; + const respond = opts?.forceNoResponse + ? () => {} + : () => call("NOTIFY_RESP", { subscriptionId: id }); + const clear = on(id, (...args) => { + respond(); + callback(...args); + }); + return () => { + clear(); + return call("DELETE", { paths: newSubPath }); + }; + }; export default { name: "subscribe", diff --git a/src/configurations/build.ts b/src/configurations/build.ts index 80c2e366fb4a13a3ca438d1a2154f9d9eb6f74c2..0b4ba79feeba81b1e3e7545ffbb8c7b9a94d6911 100644 --- a/src/configurations/build.ts +++ b/src/configurations/build.ts @@ -254,6 +254,7 @@ const buildConnect: BuildConnectionFn = supportedProto: (proto) => call("GET_SUPPORTED_PROTO", { proto }), _operate: (path, id, resp, input, commandKey) => call("OPERATE", { path, input, id, resp, commandKey }), + _notifyResp: (subscriptionId) => call("NOTIFY_RESP", { subscriptionId }), on, ...makeRecipes(call, on), disconnect: () => client.end(), diff --git a/src/types.ts b/src/types.ts index 67c97dc2d99949ff0ec0fc4d012f11fad4025fe6..612c5b6ef296eb032edd9f796998d352bb0ce24a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -7,6 +7,7 @@ export type CommandType = | "DELETE" | "OPERATE" | "NOTIFY" + | "NOTIFY_RESP" | "GET_SUPPORTED_DM" | "GET_INSTANCES" | "GET_SUPPORTED_PROTO"; @@ -238,7 +239,8 @@ export type PbRequestCommand = | PbRequestCommandOperate | PbRequestCommandSupport | PbRequestCommandInstance - | PbRequestCommandSupportProto; + | PbRequestCommandSupportProto + | PbRequestCommandNotifyResp; export interface SuportedCommandOpts { firstLevelOnly?: boolean; @@ -258,6 +260,12 @@ export type InputRecord = { | boolean; } & { allowPartial?: boolean }; +export type PbRequestCommandNotifyResp = { + notifyResp: { + subscriptionId: string; + }; +}; + export type PbRequestCommandSupportProto = { getSupportedProtocol: { controllerSupportedProtocolVersions: string; @@ -607,6 +615,7 @@ export interface SubscriptionOptions { id?: string; notif: NotifType; retry?: boolean; + forceNoResponse?: boolean; reference: string | string[]; }