@basmilius/apple-companion-link 0.0.74 → 0.0.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -4
- package/package.json +4 -3
- package/dist/index.js.map +0 -17
package/dist/index.js
CHANGED
|
@@ -1,4 +1 @@
|
|
|
1
|
-
var f={Up:1,Down:2,Left:3,Right:4,Menu:5,Select:6,Home:7,VolumeUp:8,VolumeDown:9,Siri:10,Screensaver:11,Sleep:12,Wake:13,PlayPause:14,ChannelIncrement:15,ChannelDecrement:16,Guide:17,PageUp:18,PageDown:19},C={Play:1,Pause:2,NextTrack:3,PreviousTrack:4,GetVolume:5,SetVolume:6,SkipBy:7,FastForwardBegin:8,FastForwardEnd:9,RewindBegin:10,RewindEnd:11,GetCaptionSettings:12,SetCaptionSettings:13};function A(t){switch(t){case 1:return"asleep";case 2:return"screensaver";case 3:return"awake";case 4:return"idle";default:return"unknown"}}import{randomInt as K}from"node:crypto";import{OPack as R,Plist as O,reporter as F,waitFor as T}from"@basmilius/apple-common";var o={Unknown:0,Noop:1,PS_Start:3,PS_Next:4,PV_Start:5,PV_Next:6,U_OPACK:7,E_OPACK:8,P_OPACK:9,PA_Request:10,PA_Response:11,SessionStartRequest:16,SessionStartResponse:17,SessionData:18,FamilyIdentityRequest:32,FamilyIdentityResponse:33,FamilyIdentityUpdate:34},n={Event:1,Request:2,Response:3},k=[o.PS_Start,o.PS_Next,o.PV_Start,o.PV_Next,o.U_OPACK,o.E_OPACK,o.P_OPACK],x=[o.PS_Start,o.PS_Next,o.PV_Start,o.PV_Next];class h{get socket(){return this.#t.socket}#t;constructor(t){this.#t=t}async fetchMediaControlStatus(){await this.socket.exchange(o.E_OPACK,{_i:"FetchMediaControlStatus",_t:n.Request,_c:{}})}async fetchNowPlayingInfo(){await this.socket.exchange(o.E_OPACK,{_i:"FetchCurrentNowPlayingInfoEvent",_t:n.Request,_c:{}})}async fetchSupportedActions(){await this.socket.exchange(o.E_OPACK,{_i:"FetchSupportedActionsEvent",_t:n.Request,_c:{}})}async getAttentionState(){let[,t]=await this.socket.exchange(o.E_OPACK,{_i:"FetchAttentionState",_t:n.Request,_c:{}}),{_c:e}=_(t);return A(e.state)}async getLaunchableApps(){let[,t]=await this.socket.exchange(o.E_OPACK,{_i:"FetchLaunchableApplicationsEvent",_t:n.Request,_c:{}}),{_c:e}=_(t);return Object.entries(e).map(([i,s])=>({bundleId:i,name:s}))}async getSiriRemoteInfo(){let[,t]=await this.socket.exchange(o.E_OPACK,{_i:"FetchSiriRemoteInfo",_t:n.Request,_c:{}});return O.parse(Buffer.from(t._c.SiriRemoteInfoKey).buffer)}async getUserAccounts(){let[,t]=await this.socket.exchange(o.E_OPACK,{_i:"FetchUserAccountsEvent",_t:n.Request,_c:{}}),{_c:e}=_(t);return Object.entries(e).map(([i,s])=>({accountId:i,name:s}))}async hidCommand(t,e=!1){await this.socket.exchange(o.E_OPACK,{_i:"_hidC",_t:n.Request,_c:{_hBtS:e?1:2,_hidC:f[t]}})}async launchApp(t){await this.socket.exchange(o.E_OPACK,{_i:"_launchApp",_t:n.Request,_c:{_bundleID:t}})}async launchUrl(t){await this.socket.exchange(o.E_OPACK,{_i:"_launchApp",_t:n.Request,_c:{_urlS:t}})}async mediaControlCommand(t,e){let[,i]=await this.socket.exchange(o.E_OPACK,{_i:"_mcc",_t:n.Request,_c:{_mcc:C[t],...e||{}}});return _(i)}async pressButton(t,e="SingleTap",i=500){switch(e){case"DoubleTap":await this.hidCommand(t,!0),await this.hidCommand(t,!1),await this.hidCommand(t,!0),await this.hidCommand(t,!1);break;case"Hold":await this.hidCommand(t,!0),await T(i),await this.hidCommand(t,!1);break;case"SingleTap":await this.hidCommand(t,!0),await this.hidCommand(t,!1);break}}async switchUserAccount(t){await this.socket.exchange(o.E_OPACK,{_i:"SwitchUserAccountEvent",_t:n.Request,_c:{SwitchAccountID:t}})}async _subscribe(t,e){this.socket.on(t,e),await this.socket.send(o.E_OPACK,{_i:"_interest",_t:n.Event,_c:{_regEvents:[t]}})}async _unsubscribe(t,e){if(e)this.socket.off(t,e);await this.socket.send(o.E_OPACK,{_i:"_interest",_t:n.Event,_c:{_deregEvents:[t]}})}async _sessionStart(){let[,t]=await this.socket.exchange(o.E_OPACK,{_i:"_sessionStart",_t:n.Request,_c:{_srvT:"com.apple.tvremoteservices",_sid:K(0,4294967295)}});return _(t)}async _systemInfo(t){let[,e]=await this.socket.exchange(o.E_OPACK,{_i:"_systemInfo",_t:n.Request,_c:{_bf:0,_cf:512,_clFl:128,_i:"cafecafecafe",_idsID:t.toString(),_pubID:"FF:70:79:61:74:76",_sf:256,_sv:"170.18",model:"iPhone10,6",name:"Bas Companion Link"}});return _(e)}async _touchStart(){let[,t]=await this.socket.exchange(o.E_OPACK,{_i:"_touchStart",_t:n.Request,_c:{_height:R.float(1000),_tFl:0,_width:R.float(1000)}});return _(t)}async _tvrcSessionStart(){let[,t]=await this.socket.exchange(o.E_OPACK,{_i:"TVRCSessionStart",_t:n.Request,_btHP:!1,_inUseProc:"tvremoted",_c:{}});return _(t)}}function _(t){if(typeof t==="object")return t;throw F.error("Expected an object.",{obj:t}),Error("Expected an object.")}import{AccessoryPair as V}from"@basmilius/apple-common";class P{get internal(){return this.#t}get socket(){return this.#s.socket}#t;#s;constructor(t){this.#t=new V(this.#e.bind(this)),this.#s=t}async start(){await this.#t.start()}async pin(t){return this.#t.pin(t)}async transient(){return this.#t.transient()}async#e(t,e){let i=t==="m1"?o.PS_Start:o.PS_Next,[,s]=await this.socket.exchange(i,{_pd:e,_pwTy:1});if(typeof s!=="object"||s===null)throw Error("Invalid response from receiver.");return s._pd}}import{randomInt as I}from"node:crypto";import{Socket as U}from"node:net";import{BaseSocket as B,Chacha20 as v,OPack as S,reporter as a}from"@basmilius/apple-common";var d=4;class y extends B{get isConnected(){return this.#t.readyState==="open"}get isEncrypted(){return!!this.#o&&!!this.#n}#t;#s={};#e=Buffer.alloc(0);#i;#o;#c;#n;#r;constructor(t,e){super(t,e);this.#r=I(0,65536),this.onClose=this.onClose.bind(this),this.onConnect=this.onConnect.bind(this),this.onData=this.onData.bind(this),this.onEnd=this.onEnd.bind(this),this.onError=this.onError.bind(this),this.#t=new U,this.#t.on("close",this.onClose),this.#t.on("connect",this.onConnect),this.#t.on("data",this.onData),this.#t.on("end",this.onEnd),this.#t.on("error",this.onError)}async connect(){return a.net(`Connecting to ${this.address}:${this.port}...`),await new Promise((t)=>{this.#t.connect({host:this.address,port:this.port,keepAlive:!0},t)})}async disconnect(){this.#t.destroy()}async enableEncryption(t,e){this.#o=t,this.#n=e,this.#i=0,this.#c=0}async exchange(t,e){let i=this.#r;return new Promise((s,r)=>{if(x.includes(t))this.#s[-1]=s;else this.#s[i]=s;this.send(t,e).catch(r)})}async send(t,e){let i=this.#r++;e._x??=S.sizedInt(i,8);let s=Buffer.from(S.encode(e)),r=s.byteLength;if(this.isEncrypted&&r>0)r+=16;let m=Buffer.alloc(4);m.writeUint8(t,0),m.writeUintBE(r,1,3);let c;if(this.isEncrypted){let p=Buffer.alloc(12);p.writeBigUInt64LE(BigInt(this.#c++),0);let u=v.encrypt(this.#n,p,m,s);c=Buffer.concat([m,u.ciphertext,u.authTag])}else c=Buffer.concat([m,s]);return a.raw("Send data frame",this.isEncrypted,Buffer.from(c).toString("hex"),e),new Promise((p,u)=>{this.#t.write(c,(g)=>g&&u(g)),p()})}async onClose(){await super.onClose(),a.net(`Connection closed from ${this.address}:${this.port}`)}async onConnect(){await super.onConnect(),a.net(`Connected to ${this.address}:${this.port}`)}async onData(t){this.#e=Buffer.concat([this.#e,t]);while(this.#e.byteLength>=d){let e=this.#e.subarray(0,d),i=e.readUintBE(1,3),s=d+i;if(this.#e.byteLength<s){a.warn(`Not enough data yet, waiting on the next frame.. needed=${s} available=${this.#e.byteLength} receivedLength=${t.byteLength}`);return}a.raw(`Frame found length=${s} availableLength=${this.#e.byteLength} receivedLength=${t.byteLength}`);let r=Buffer.from(this.#e.subarray(0,s));this.#e=this.#e.subarray(s),a.raw(`Handle frame, ${this.#e.byteLength} bytes left...`);let c=(await this.#a(r)).subarray(4,s);await this.#m(e,c)}}async onEnd(){a.net("Connection ended")}async onError(t){await super.onError(t),a.error("Error received",t)}async#a(t){if(!this.isEncrypted)return t;let e=t.subarray(0,4),i=e.readUintBE(1,3),s=t.subarray(4,4+i),r=s.subarray(s.byteLength-16),m=s.subarray(0,s.byteLength-16),c=Buffer.alloc(12);c.writeBigUint64LE(BigInt(this.#i++),0);let p=v.decrypt(this.#o,c,e,m,r);return Buffer.concat([e,p,r])}async#m(t,e){let i=t.readInt8();if(!k.includes(i)){a.warn("Packet not handled, no opack frame.");return}if(e=S.decode(e),a.raw("Decoded OPACK",{header:t,payload:e}),"_x"in e){let s=e._x;if(s in this.#s)(this.#s[s]??null)?.([t,e]),delete this.#s[s];else if("_i"in e)this.emit(e._i,e._c);else{let r=e._c,m=Object.keys(r).map((c)=>c.substring(0,-3));for(let c of m)this.emit(c,r[c])}}else if(this.#s[-1])(this.#s[-1]??null)?.([t,e]),delete this.#s[-1];else a.warn("No handler for message",[t,e])}}import{AccessoryVerify as q,hkdf as E}from"@basmilius/apple-common";class l{get socket(){return this.#s.socket}#t;#s;constructor(t){this.#t=new q(this.#e.bind(this)),this.#s=t}async start(t){let e=await this.#t.start(t),i=E({hash:"sha512",key:e.sharedSecret,length:32,salt:Buffer.alloc(0),info:Buffer.from("ServerEncrypt-main")}),s=E({hash:"sha512",key:e.sharedSecret,length:32,salt:Buffer.alloc(0),info:Buffer.from("ClientEncrypt-main")});return{accessoryToControllerKey:i,controllerToAccessoryKey:s,pairingId:e.pairingId,sharedSecret:e.sharedSecret}}async#e(t,e){let i=t==="m1"?o.PV_Start:o.PV_Next,[,s]=await this.socket.exchange(i,{_pd:e,_auTy:4});if(typeof s!=="object"||s===null)throw Error("Invalid response from receiver.");return s._pd}}class w{get api(){return this.#t}get device(){return this.#s}get socket(){return this.#e}get pairing(){return this.#i}get verify(){return this.#o}#t;#s;#e;#i;#o;constructor(t){this.#s=t,this.#e=new y(t.address,t.service.port),this.#t=new h(this),this.#i=new P(this),this.#o=new l(this)}async connect(){await this.#e.connect()}async disconnect(){await this.#e.disconnect()}}export{A as convertAttentionState,C as MediaControlCommand,f as HidCommand,w as CompanionLink};
|
|
2
|
-
|
|
3
|
-
//# debugId=E00B066B0AF3EB3A64756E2164756E21
|
|
4
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
var co={Up:1,Down:2,Left:3,Right:4,Menu:5,Select:6,Home:7,VolumeUp:8,VolumeDown:9,Siri:10,Screensaver:11,Sleep:12,Wake:13,PlayPause:14,ChannelIncrement:15,ChannelDecrement:16,Guide:17,PageUp:18,PageDown:19},to={Play:1,Pause:2,NextTrack:3,PreviousTrack:4,GetVolume:5,SetVolume:6,SkipBy:7,FastForwardBegin:8,FastForwardEnd:9,RewindBegin:10,RewindEnd:11,GetCaptionSettings:12,SetCaptionSettings:13};function mo(o){switch(o){case 1:return"asleep";case 2:return"screensaver";case 3:return"awake";case 4:return"idle";default:return"unknown"}}import{randomInt as Cs}from"node:crypto";import{reporter as ws,waitFor as ks}from"@basmilius/apple-common";var Y=978307200000,J="bplist00";var Ao;(function(o){o[o.BINARY=0]="BINARY",o[o.XML=1]="XML",o[o.OPENSTEP=2]="OPENSTEP"})(Ao||(Ao={}));var K=1e8,qo=32768,Co=new TextDecoder("utf-8"),To=new TextDecoder("utf-16");function wo(o,s=0){return new DataView(o).getFloat64(s,!1)}function Vo(o,s=0){return new DataView(o).getFloat32(s,!1)}function L(o,s=0){return new DataView(o).getUint8(s)}function $o(o,s=0){return new DataView(o).getUint16(s,!1)}function Go(o,s=0){return new DataView(o).getUint32(s,!1)}function Q(o,s=0){return new DataView(o).getBigUint64(s,!1)}function R(o){switch(o.byteLength){case 1:return L(o);case 2:return $o(o);case 4:return Go(o);case 8:return Q(o);case 16:return Q(o,8)}throw Error(`Invalid unsigned int length: ${o.byteLength}`)}function ko(o,s=0){return new DataView(o).getInt8(s)}function Lo(o,s=0){return new DataView(o).getInt16(s,!1)}function Wo(o,s=0){return new DataView(o).getInt32(s,!1)}function Xo(o,s=0){return new DataView(o).getBigInt64(s,!1)}function Ho(o){switch(o.byteLength){case 1:return ko(o);case 2:return Lo(o);case 4:return Wo(o);case 8:return Xo(o);case 16:return Q(o,8)}throw Error(`Invalid int length: ${o.byteLength}`)}function Jo(o){let s=new Uint8Array(o);for(let n=0;n<s.length;n+=2){let c=s[n];s[n]=s[n+1],s[n+1]=c}return s.buffer}var Eo=(o)=>{let s=o.slice(0,J.length);if(Co.decode(s)!==J)throw Error(`Invalid binary plist. Expected '${J}' at offset 0.`);let n=o.slice(o.byteLength-32,o.byteLength),c=L(n,6),i=L(n,7),t=Number(Q(n,8)),m=Number(Q(n,16)),_=Number(Q(n,24));if(t>qo)throw Error("maxObjectCount exceeded");let w=[];for(let x=0;x<t;x++){let p=o.slice(_+x*c,_+(x+1)*c);w[x]=Number(R(p))}function S(x){let p=w[x],q=L(o,p),T=(q&240)>>4,e=q&15;switch(T){case 0:return oo();case 1:return so();case 8:return no();case 2:return io();case 3:return V();case 4:return H();case 5:return O();case 6:return O(!0);case 10:return r();case 13:return P();default:throw Error("Unhandled type 0x"+T.toString(16))}function oo(){switch(e){case 0:return null;case 8:return!1;case 9:return!0;case 15:return null;default:throw Error("Unhandled simple type 0x"+T.toString(16))}}function so(){let a=Math.pow(2,e);if(a<K){let A=o.slice(p+1,p+1+a);return Ho(A)}throw Error("Too little heap space available! Wanted to read "+a+" bytes, but only "+K+" are available.")}function no(){let a=e+1;if(a<K)return{CF$UID:R(o.slice(p+1,p+1+a))};throw Error("Too little heap space available! Wanted to read "+a+" bytes, but only "+K+" are available.")}function io(){let a=Math.pow(2,e);if(a<K){let A=o.slice(p+1,p+1+a);if(a===4)return Vo(A);else if(a===8)return wo(A);throw Error(`Invalid real length: ${a}`)}else throw Error("Too little heap space available! Wanted to read "+a+" bytes, but only "+K+" are available.")}function V(){if(e!=3)console.error("Unknown date type :"+e+". Parsing anyway...");let a=o.slice(p+1,p+9);return new Date(Y+1000*wo(a))}function H(){let a=1,A=e;if(e==15){let B=ko(o,p+1),C=(B&240)/16;if(C!=1)console.error("0x4: UNEXPECTED LENGTH-INT TYPE! "+C);let F=B&15,N=Math.pow(2,F);a=2+N,A=Number(R(o.slice(p+2,p+2+N)))}if(A<K)return o.slice(p+a,p+a+Number(A));throw Error("Too little heap space available! Wanted to read "+A+" bytes, but only "+K+" are available.")}function O(a=!1){let A=e,B=1;if(e==15){let C=L(o,p+1),F=(C&240)/16;if(F!=1)console.error("UNEXPECTED LENGTH-INT TYPE! "+F);let N=C&15,M=Math.pow(2,N);B=2+M,A=Number(R(o.slice(p+2,p+2+M)))}if(A*=a?2:1,A<K){let C=o.slice(p+B,p+B+A);if(a)return C=Jo(C),To.decode(C);else return Co.decode(C)}throw Error("Too little heap space available! Wanted to read "+A+" bytes, but only "+K+" are available.")}function r(){let a=e,A=1;if(e==15){let C=L(o,p+1),F=(C&240)/16;if(F!=1)console.error("0xa: UNEXPECTED LENGTH-INT TYPE! "+F);let N=C&15,M=Math.pow(2,N);A=2+M,a=Number(R(o.slice(p+2,p+2+M)))}if(a*i>K)throw Error("Too little heap space available!");let B=[];for(let C=0;C<a;C++){let F=Number(R(o.slice(p+A+C*i,p+A+(C+1)*i)));B[C]=S(F)}return B}function P(){let a=e,A=1;if(e==15){let C=L(o,p+1),F=(C&240)/16;if(F!=1)console.error("0xD: UNEXPECTED LENGTH-INT TYPE! "+F);let N=C&15,M=Math.pow(2,N);A=2+M,a=Number(R(o.slice(p+2,p+2+M)))}if(a*2*i>K)throw Error("Too little heap space available!");let B={};for(let C=0;C<a;C++){let F=Number(R(o.slice(p+A+C*i,p+A+(C+1)*i))),N=Number(R(o.slice(p+A+a*i+C*i,p+A+a*i+(C+1)*i))),M=S(F);if(typeof M!=="string")throw Error("Invalid key type.");if(M==="__proto__")throw Error("Attempted prototype pollution");let Ro=S(N);B[M]=Ro}return B}}return S(m)};var ro=new TextEncoder,Qo=new Uint8Array([0,0,0,0,0,0]),Zo=(o)=>Uint8Array.from(o.match(/.{1,2}/g).map((s)=>parseInt(s,16))),So=(o)=>!!o&&typeof o==="object"&&Object.keys(o).length==1&&typeof o.CF$UID==="number",Do=(o)=>{let s=new ArrayBuffer(o.length*2),n=new Uint16Array(s);for(let c=0,i=o.length;c<i;c++)n[c]=o.charCodeAt(c);return new Uint8Array(s)},Z=(o,s)=>{let n=new Uint8Array(o.length+s.length);return n.set(o),n.set(s,o.length),n},E=(o,s,n)=>{let c=new Uint8Array(o.length+n),i=new DataView(c.buffer);switch(c.set(o),n){case 1:i.setUint8(o.length,Number(s));break;case 2:i.setUint16(o.length,Number(s),!1);break;case 4:i.setUint32(o.length,Number(s),!1);break;case 8:i.setBigUint64(o.length,BigInt(s),!1);break;default:throw Error("Unsupported int size")}return c},Uo=(o,s,n)=>{let c=new Uint8Array(o.length+n),i=new DataView(c.buffer);switch(c.set(o),n){case 1:i.setInt8(o.length,Number(s));break;case 2:i.setInt16(o.length,Number(s),!1);break;case 4:i.setInt32(o.length,Number(s),!1);break;case 8:i.setBigInt64(o.length,BigInt(s),!1);break;default:throw Error("Unsupported int size")}return c},yo=(o,s)=>{let n=new Uint8Array(o.length+8),c=new DataView(n.buffer);return n.set(o),c.setFloat64(o.length,s),n},go=(o)=>{let s=ro.encode(J);if(o instanceof Array&&o.length===1)o=o[0];let n=v(o),c=jo(n.length),i=[],t,m;return _(),n.forEach((r,P)=>{if(i[P]=s.byteLength,typeof r>"u"||r===null)s=E(s,0,1);else x(r)}),S(),w(),s.buffer;function _(){let r={},P=0;n.forEach((a)=>{if(a.id)return;if(typeof a.value==="string")if(r.hasOwnProperty(a.value))a.type="stringref",a.id=r[a.value];else r[a.value]=a.id=P++;else a.id=P++}),n=n.filter((a)=>{return a.type!=="stringref"})}function w(){s=Z(s,Qo),s=Z(s,new Uint8Array([t,c])),s=E(s,BigInt(n.length),8),s=E(s,BigInt("0"),8),s=E(s,BigInt(m),8)}function S(){m=s.byteLength,t=zo(m),i.forEach((r)=>{s=E(s,r,t)})}function x(r){if(r.type==="primitive"){let P=r.value;switch(typeof P){case"number":case"bigint":T(P);break;case"string":no(P);break;case"boolean":so(P);break}if(P instanceof Date)p(P);else if(P instanceof ArrayBuffer)io(P);else if(So(P))e(P.CF$UID);return}switch(r.type){case"dict":q(r);break;case"array":oo(r);break;default:throw Error("unhandled entry type: "+r.type)}}function p(r){s=E(s,51,1);let P=(r.getTime()-Y)/1000;s=yo(s,P)}function q(r){V(13,r.entryKeys.length),r.entryKeys.forEach((P)=>{H(P.id)}),r.entryValues.forEach((P)=>{H(P.id)})}function T(r){if(typeof r==="bigint"){let a=r.toString(16),A=Zo(a.padStart(32,"0").slice(0,32));s=E(s,20,1),s=Z(s,A)}else if(Number.isInteger(r))if(r<0)s=E(s,19,1),s=Uo(s,r,8);else if(r<=255)s=E(s,16,1),s=E(s,r,1);else if(r<=65535)s=E(s,17,1),s=E(s,r,2);else if(r<=4294967295)s=E(s,18,1),s=E(s,r,4);else s=E(s,19,1),s=E(s,r,8);else s=E(s,35,1),s=yo(s,r)}function e(r){V(8,0),H(r)}function oo(r){V(10,r.entries.length),r.entries.forEach((P)=>{H(P.id)})}function so(r){s=E(s,r?9:8,1)}function no(r){if(O(r)){let P=Do(r);V(6,P.length/2);for(let a=0;a<P.length;a+=2){let A=P[a+0];P[a+0]=P[a+1],P[a+1]=A}s=Z(s,P)}else{let P=ro.encode(r);V(5,P.length),s=Z(s,P)}}function io(r){V(4,r.byteLength),s=Z(s,new Uint8Array(r))}function V(r,P){if(P<15)s=E(s,(r<<4)+P,1);else s=E(s,(r<<4)+15,1),T(P)}function H(r){s=E(s,r,c)}function O(r){return ro.encode(r).byteLength!=r.length}},Oo=["string","number","boolean","bigint"];function v(o){if(Oo.includes(typeof o)||o instanceof ArrayBuffer||o instanceof Date||So(o))return[{type:"primitive",value:o}];if(o!=null&&typeof o==="object")return Array.isArray(o)?Yo(o):vo(o);throw Error("unhandled entry: "+o)}function Yo(o){let s=o.map(v);return[{type:"array",value:void 0,entries:s.map((n)=>n[0])},...s.flat()]}function vo(o){let s=Object.keys(o).map(v).flat(1),n=Object.values(o).map(v);return[{type:"dict",value:void 0,entryKeys:s,entryValues:n.map((c)=>c[0])},...s,...n.flat()]}function zo(o){if(o<256)return 1;if(o<65536)return 2;if(o<4294967296)return 4;return 8}function jo(o){if(o<256)return 1;if(o<65536)return 2;return 4}var Io=Object.defineProperty,j=(o,s)=>{for(var n in s)Io(o,n,{get:s[n],enumerable:!0,configurable:!0,set:(c)=>s[n]=()=>c})},uo={};j(uo,{parts:()=>os,ns:()=>xo,now:()=>fo,encode:()=>ns,decode:()=>ss});var bo=0x83AA7E80n;function fo(){let o=xo()/1000n,s=o/1000000n,n=o-s*1000000n;return s+bo<<32n|(n<<32n)/1000000n}function xo(){return process.hrtime.bigint()}function os(o){return[Number(o>>32n),Number(o&0xFFFFFFFFn)]}function ss(o){return{proto:o.readUInt8(0),type:o.readUInt8(1),seqno:o.readUInt16BE(2),padding:o.readUInt32BE(4),reftime_sec:o.readUInt32BE(8),reftime_frac:o.readUInt32BE(12),recvtime_sec:o.readUInt32BE(16),recvtime_frac:o.readUInt32BE(20),sendtime_sec:o.readUInt32BE(24),sendtime_frac:o.readUInt32BE(28)}}function ns(o){let s=Buffer.alloc(32);return s.writeUInt8(o.proto,0),s.writeUInt8(o.type,1),s.writeUInt16BE(o.seqno,2),s.writeUInt32BE(o.padding,4),s.writeUInt32BE(o.reftime_sec,8),s.writeUInt32BE(o.reftime_frac,12),s.writeUInt32BE(o.recvtime_sec,16),s.writeUInt32BE(o.recvtime_frac,20),s.writeUInt32BE(o.sendtime_sec,24),s.writeUInt32BE(o.sendtime_frac,28),s}var $={};j($,{sizedInt:()=>eo,int:()=>cs,float:()=>is,encode:()=>ts,decode:()=>ms});class ao extends Number{size;constructor(o,s){super(o);this.size=s}}class _o{value;constructor(o){this.value=o}}class po{value;constructor(o){this.value=o}}function eo(o,s){return new ao(o,s)}function is(o){return new _o(o)}function cs(o){return new po(o)}function k(o){let s=o.reduce((i,t)=>i+t.length,0),n=new Uint8Array(s),c=0;for(let i of o)n.set(i,c),c+=i.length;return n}function h(o){return Uint8Array.of(o)}function y(o,s){let n=new Uint8Array(s),c=BigInt(o);for(let i=0;i<s;i++)n[i]=Number(c&0xffn),c>>=8n;return n}function W(o){let s=o.reduce((i,t)=>i+t.length,0),n=new Uint8Array(s),c=0;for(let i of o)n.set(i,c),c+=i.length;return n}function ts(o){return z(o,[])}function z(o,s){let n=null;if(o===null||o===void 0)n=h(4);else if(typeof o==="boolean")n=h(o?1:2);else if(o instanceof _o){let i=new ArrayBuffer(8);new DataView(i).setFloat64(0,o.value,!0),n=k([h(54),new Uint8Array(i)])}else if(o instanceof po){let i=o.value;if(i<40)n=h(8+i);else if(i<=255)n=W([h(48),y(i,1)]);else if(i<=65535)n=W([h(49),y(i,2)]);else if(i<=4294967295)n=W([h(50),y(i,4)]);else n=W([h(51),y(i,8)])}else if(typeof o==="number")if(!Number.isInteger(o)){let i=new ArrayBuffer(8);new DataView(i).setFloat64(0,o,!0),n=k([h(54),new Uint8Array(i)])}else if(o<40)n=h(8+o);else if(o<=255)n=k([h(48),y(o,1)]);else if(o<=65535)n=k([h(49),y(o,2)]);else if(o<=4294967295)n=k([h(50),y(o,4)]);else n=k([h(51),y(o,8)]);else if(o instanceof ao)n=k([h(48+Math.log2(o.size)),y(o.valueOf(),o.size)]);else if(typeof o==="string"){let i=new TextEncoder().encode(o),t=i.length;if(t<=32)n=k([h(64+t),i]);else if(t<=255)n=k([h(97),y(t,1),i]);else if(t<=65535)n=k([h(98),y(t,2),i]);else if(t<=16777215)n=k([h(99),y(t,3),i]);else n=k([h(100),y(t,4),i])}else if(o instanceof Uint8Array||Buffer.isBuffer(o)){let i=o instanceof Uint8Array?o:new Uint8Array(o),t=i.length;if(t<=32)n=k([h(112+t),i]);else if(t<=255)n=k([h(145),y(t,1),i]);else if(t<=65535)n=k([h(146),y(t,2),i]);else n=k([h(147),y(t,4),i])}else if(Array.isArray(o)){let i=k(o.map((m)=>z(m,s))),t=o.length;if(t<=15){if(n=k([h(208+t),i]),t>=15)n=k([n,h(3)])}else n=k([h(223),i,h(3)])}else if(typeof o==="object"){let i=Object.keys(o),t=i.length,m=[];for(let w of i)m.push(z(w,s)),m.push(z(o[w],s));let _;if(t<=15)_=h(224+t);else _=h(239);if(n=W([_,W(m)]),t>=15||s.some((w)=>w===n))n=W([n,h(129)])}else throw TypeError(typeof o);let c=s.findIndex((i)=>i.length===n.length&&i.every((t,m)=>t===n[m]));if(c>=0)if(c<33)n=h(160+c);else if(c<=255)n=k([h(193),y(c,1)]);else if(c<=65535)n=k([h(194),y(c,2)]);else if(c<=4294967295)n=k([h(195),y(c,4)]);else n=k([h(196),y(c,8)]);else if(n.length>1)s.push(n);return n}function ms(o){let[s]=X(o,[]);return s}function rs(o,s){if(o.length<s)throw TypeError(`Not enough data: need ${s} bytes, have ${o.length}`)}function U(o,s,n){rs(o.subarray(s),n);let c=0n;for(let i=n-1;i>=0;i--)c=c<<8n|BigInt(o[s+i]);return Number(c)}function X(o,s){if(o.length===0)throw TypeError("No data to unpack");let n=o[0],c=!0,i,t;if(n===1)i=!0,t=o.subarray(1);else if(n===2)i=!1,t=o.subarray(1);else if(n===4)i=null,t=o.subarray(1);else if(n===5)i=o.subarray(1,17),t=o.subarray(17);else if(n===6)i=U(o,1,8),t=o.subarray(9);else if(n>=8&&n<=47)i=n-8,t=o.subarray(1);else if(n===53)i=new DataView(o.buffer,o.byteOffset+1,4).getFloat32(0,!0),t=o.subarray(5);else if(n===54)i=new DataView(o.buffer,o.byteOffset+1,8).getFloat64(0,!0),t=o.subarray(9);else if((n&240)===48){let m=2**(n&15),_=U(o,1,m);i=eo(_,m),t=o.subarray(1+m)}else if(n>=64&&n<=96){let m=n-64;i=new TextDecoder().decode(o.subarray(1,1+m)),t=o.subarray(1+m)}else if(n>=97&&n<=100){let m=n&15,_=U(o,1,m);i=new TextDecoder().decode(o.subarray(1+m,1+m+_)),t=o.subarray(1+m+_)}else if(n>=112&&n<=144){let m=n-112;i=o.subarray(1,1+m),t=o.subarray(1+m)}else if(n>=145&&n<=148){let m=1<<(n&15)-1,_=U(o,1,m),w=1+m;i=o.subarray(w,w+_),t=o.subarray(w+_)}else if((n&240)===208){let m=n&15,_=o.subarray(1),w=[];if(m===15){while(_[0]!==3){let[S,x]=X(_,s);w.push(S),_=x}_=_.subarray(1)}else for(let S=0;S<m;S++){let[x,p]=X(_,s);w.push(x),_=p}i=w,t=_,c=!1}else if((n&224)===224){let m=n&15,_=o.subarray(1),w={};if(m===15){while(_[0]!==3){let[S,x]=X(_,s),[p,q]=X(x,s);w[S]=p,_=q}_=_.subarray(1)}else for(let S=0;S<m;S++){let[x,p]=X(_,s),[q,T]=X(p,s);w[x]=q,_=T}i=w,t=_,c=!1}else if(n>=160&&n<=192){let m=n-160;if(m>=s.length)throw TypeError(`Reference index ${m} out of range`);i=s[m],t=o.subarray(1),c=!1}else if(n>=193&&n<=196){let m=n-192,_=U(o,1,m);if(_>=s.length)throw TypeError(`UID ${_} out of range`);i=s[_],t=o.subarray(1+m),c=!1}else throw TypeError(`Unknown tag 0x${n.toString(16)}`);if(c)s.push(i);return[i,t]}var Po={};j(Po,{serialize:()=>go,parse:()=>Eo});var as={};j(as,{encode:()=>ls,decode:()=>As,bail:()=>hs,Value:()=>D,State:()=>Ps,Method:()=>ps,Flags:()=>_s,ErrorCode:()=>Fo});var _s={TransientPairing:16},Fo={Unknown:1,Authentication:2,BackOff:3,MaxPeers:4,MaxTries:5,Unavailable:6,Busy:7},ps={PairSetup:0,PairSetupWithAuth:1,PairVerify:2,AddPairing:3,RemovePairing:4,ListPairing:5},Ps={M1:1,M2:2,M3:3,M4:4,M5:5,M6:6},D={Method:0,Identifier:1,Salt:2,PublicKey:3,Proof:4,EncryptedData:5,State:6,Error:7,BackOff:8,Certificate:9,Signature:10,Permissions:11,FragmentData:12,FragmentLast:13,Name:17,Flags:19};function hs(o){if(o.has(D.BackOff)){let s=o.get(D.BackOff),n=s.readUintLE(0,s.length);throw Error(`Device is busy, try again in ${n} seconds.`)}if(o.has(D.Error)){let s=Object.entries(Fo).find(([n,c])=>c===o.get(D.Error).readUint8());if(!s)throw Error(`Device returned an unknown error code: ${o.get(D.Error).readUint8()}`);throw Error(`Device returned an error code: ${s[0]}`)}throw Error("Invalid response")}function ls(o){let s=[];for(let[n,c]of o){let i;if(typeof c==="number")i=Buffer.from([c]);else i=c;let t=0;do{let m=Math.min(i.length-t,255);if(s.push(n,m),m>0)for(let _=0;_<m;_++)s.push(i[t+_]);t+=m}while(t<i.length)}return Buffer.from(s)}function As(o){let s=new Map,n=0;while(n<o.length){let c=o[n++],i=o[n++],t=new Uint8Array(o).slice(n,n+i);n+=i;let m=s.get(c);if(m)s.set(c,Buffer.concat([m,t]));else s.set(c,Buffer.from(t))}return s}var l={Unknown:0,Noop:1,PS_Start:3,PS_Next:4,PV_Start:5,PV_Next:6,U_OPACK:7,E_OPACK:8,P_OPACK:9,PA_Request:10,PA_Response:11,SessionStartRequest:16,SessionStartResponse:17,SessionData:18,FamilyIdentityRequest:32,FamilyIdentityResponse:33,FamilyIdentityUpdate:34},g={Event:1,Request:2,Response:3},Bo=[l.PS_Start,l.PS_Next,l.PV_Start,l.PV_Next,l.U_OPACK,l.E_OPACK,l.P_OPACK],Mo=[l.PS_Start,l.PS_Next,l.PV_Start,l.PV_Next];class I{get socket(){return this.#o.socket}#o;constructor(o){this.#o=o}async fetchMediaControlStatus(){await this.socket.exchange(l.E_OPACK,{_i:"FetchMediaControlStatus",_t:g.Request,_c:{}})}async fetchNowPlayingInfo(){await this.socket.exchange(l.E_OPACK,{_i:"FetchCurrentNowPlayingInfoEvent",_t:g.Request,_c:{}})}async fetchSupportedActions(){await this.socket.exchange(l.E_OPACK,{_i:"FetchSupportedActionsEvent",_t:g.Request,_c:{}})}async getAttentionState(){let[,o]=await this.socket.exchange(l.E_OPACK,{_i:"FetchAttentionState",_t:g.Request,_c:{}}),{_c:s}=G(o);return mo(s.state)}async getLaunchableApps(){let[,o]=await this.socket.exchange(l.E_OPACK,{_i:"FetchLaunchableApplicationsEvent",_t:g.Request,_c:{}}),{_c:s}=G(o);return Object.entries(s).map(([n,c])=>({bundleId:n,name:c}))}async getSiriRemoteInfo(){let[,o]=await this.socket.exchange(l.E_OPACK,{_i:"FetchSiriRemoteInfo",_t:g.Request,_c:{}});return Po.parse(Buffer.from(o._c.SiriRemoteInfoKey).buffer)}async getUserAccounts(){let[,o]=await this.socket.exchange(l.E_OPACK,{_i:"FetchUserAccountsEvent",_t:g.Request,_c:{}}),{_c:s}=G(o);return Object.entries(s).map(([n,c])=>({accountId:n,name:c}))}async hidCommand(o,s=!1){await this.socket.exchange(l.E_OPACK,{_i:"_hidC",_t:g.Request,_c:{_hBtS:s?1:2,_hidC:co[o]}})}async launchApp(o){await this.socket.exchange(l.E_OPACK,{_i:"_launchApp",_t:g.Request,_c:{_bundleID:o}})}async launchUrl(o){await this.socket.exchange(l.E_OPACK,{_i:"_launchApp",_t:g.Request,_c:{_urlS:o}})}async mediaControlCommand(o,s){let[,n]=await this.socket.exchange(l.E_OPACK,{_i:"_mcc",_t:g.Request,_c:{_mcc:to[o],...s||{}}});return G(n)}async pressButton(o,s="SingleTap",n=500){switch(s){case"DoubleTap":await this.hidCommand(o,!0),await this.hidCommand(o,!1),await this.hidCommand(o,!0),await this.hidCommand(o,!1);break;case"Hold":await this.hidCommand(o,!0),await ks(n),await this.hidCommand(o,!1);break;case"SingleTap":await this.hidCommand(o,!0),await this.hidCommand(o,!1);break}}async switchUserAccount(o){await this.socket.exchange(l.E_OPACK,{_i:"SwitchUserAccountEvent",_t:g.Request,_c:{SwitchAccountID:o}})}async _subscribe(o,s){this.socket.on(o,s),await this.socket.send(l.E_OPACK,{_i:"_interest",_t:g.Event,_c:{_regEvents:[o]}})}async _unsubscribe(o,s){if(s)this.socket.off(o,s);await this.socket.send(l.E_OPACK,{_i:"_interest",_t:g.Event,_c:{_deregEvents:[o]}})}async _sessionStart(){let[,o]=await this.socket.exchange(l.E_OPACK,{_i:"_sessionStart",_t:g.Request,_c:{_srvT:"com.apple.tvremoteservices",_sid:Cs(0,4294967295)}});return G(o)}async _systemInfo(o){let[,s]=await this.socket.exchange(l.E_OPACK,{_i:"_systemInfo",_t:g.Request,_c:{_bf:0,_cf:512,_clFl:128,_i:"cafecafecafe",_idsID:o.toString(),_pubID:"FF:70:79:61:74:76",_sf:256,_sv:"170.18",model:"iPhone10,6",name:"Bas Companion Link"}});return G(s)}async _touchStart(){let[,o]=await this.socket.exchange(l.E_OPACK,{_i:"_touchStart",_t:g.Request,_c:{_height:$.float(1000),_tFl:0,_width:$.float(1000)}});return G(o)}async _tvrcSessionStart(){let[,o]=await this.socket.exchange(l.E_OPACK,{_i:"TVRCSessionStart",_t:g.Request,_btHP:!1,_inUseProc:"tvremoted",_c:{}});return G(o)}}function G(o){if(typeof o==="object")return o;throw ws.error("Expected an object.",{obj:o}),Error("Expected an object.")}import{AccessoryPair as Es}from"@basmilius/apple-common";class u{get internal(){return this.#o}get socket(){return this.#n.socket}#o;#n;constructor(o){this.#o=new Es(this.#s.bind(this)),this.#n=o}async start(){await this.#o.start()}async pin(o){return this.#o.pin(o)}async transient(){return this.#o.transient()}async#s(o,s){let n=o==="m1"?l.PS_Start:l.PS_Next,[,c]=await this.socket.exchange(n,{_pd:s,_pwTy:1});if(typeof c!=="object"||c===null)throw Error("Invalid response from receiver.");return c._pd}}import{randomInt as ys}from"node:crypto";import{Socket as Ss}from"node:net";import{BaseSocket as gs,Chacha20 as Ko,reporter as d}from"@basmilius/apple-common";var ho=4;class b extends gs{get isConnected(){return this.#o.readyState==="open"}get isEncrypted(){return!!this.#i&&!!this.#t}#o;#n={};#s=Buffer.alloc(0);#c;#i;#r;#t;#m;constructor(o,s){super(o,s);this.#m=ys(0,65536),this.onClose=this.onClose.bind(this),this.onConnect=this.onConnect.bind(this),this.onData=this.onData.bind(this),this.onEnd=this.onEnd.bind(this),this.onError=this.onError.bind(this),this.#o=new Ss,this.#o.on("close",this.onClose),this.#o.on("connect",this.onConnect),this.#o.on("data",this.onData),this.#o.on("end",this.onEnd),this.#o.on("error",this.onError)}async connect(){return d.net(`Connecting to ${this.address}:${this.port}...`),await new Promise((o)=>{this.#o.connect({host:this.address,port:this.port,keepAlive:!0},o)})}async disconnect(){this.#o.destroy()}async enableEncryption(o,s){this.#i=o,this.#t=s,this.#c=0,this.#r=0}async exchange(o,s){let n=this.#m;return new Promise((c,i)=>{if(Mo.includes(o))this.#n[-1]=c;else this.#n[n]=c;this.send(o,s).catch(i)})}async send(o,s){let n=this.#m++;s._x??=$.sizedInt(n,8);let c=Buffer.from($.encode(s)),i=c.byteLength;if(this.isEncrypted&&i>0)i+=16;let t=Buffer.alloc(4);t.writeUint8(o,0),t.writeUintBE(i,1,3);let m;if(this.isEncrypted){let _=Buffer.alloc(12);_.writeBigUInt64LE(BigInt(this.#r++),0);let w=Ko.encrypt(this.#t,_,t,c);m=Buffer.concat([t,w.ciphertext,w.authTag])}else m=Buffer.concat([t,c]);return d.raw("Send data frame",this.isEncrypted,Buffer.from(m).toString("hex"),s),new Promise((_,w)=>{this.#o.write(m,(S)=>S&&w(S)),_()})}async onClose(){await super.onClose(),d.net(`Connection closed from ${this.address}:${this.port}`)}async onConnect(){await super.onConnect(),d.net(`Connected to ${this.address}:${this.port}`)}async onData(o){this.#s=Buffer.concat([this.#s,o]);while(this.#s.byteLength>=ho){let s=this.#s.subarray(0,ho),n=s.readUintBE(1,3),c=ho+n;if(this.#s.byteLength<c){d.warn(`Not enough data yet, waiting on the next frame.. needed=${c} available=${this.#s.byteLength} receivedLength=${o.byteLength}`);return}d.raw(`Frame found length=${c} availableLength=${this.#s.byteLength} receivedLength=${o.byteLength}`);let i=Buffer.from(this.#s.subarray(0,c));this.#s=this.#s.subarray(c),d.raw(`Handle frame, ${this.#s.byteLength} bytes left...`);let m=(await this.#a(i)).subarray(4,c);await this.#_(s,m)}}async onEnd(){d.net("Connection ended")}async onError(o){await super.onError(o),d.error("Error received",o)}async#a(o){if(!this.isEncrypted)return o;let s=o.subarray(0,4),n=s.readUintBE(1,3),c=o.subarray(4,4+n),i=c.subarray(c.byteLength-16),t=c.subarray(0,c.byteLength-16),m=Buffer.alloc(12);m.writeBigUint64LE(BigInt(this.#c++),0);let _=Ko.decrypt(this.#i,m,s,t,i);return Buffer.concat([s,_,i])}async#_(o,s){let n=o.readInt8();if(!Bo.includes(n)){d.warn("Packet not handled, no opack frame.");return}if(s=$.decode(s),d.raw("Decoded OPACK",{header:o,payload:s}),"_x"in s){let c=s._x;if(c in this.#n)(this.#n[c]??null)?.([o,s]),delete this.#n[c];else if("_i"in s)this.emit(s._i,s._c);else{let i=s._c,t=Object.keys(i).map((m)=>m.substring(0,-3));for(let m of t)this.emit(m,i[m])}}else if(this.#n[-1])(this.#n[-1]??null)?.([o,s]),delete this.#n[-1];else d.warn("No handler for message",[o,s])}}import{AccessoryVerify as xs,hkdf as No}from"@basmilius/apple-common";class f{get socket(){return this.#n.socket}#o;#n;constructor(o){this.#o=new xs(this.#s.bind(this)),this.#n=o}async start(o){let s=await this.#o.start(o),n=No({hash:"sha512",key:s.sharedSecret,length:32,salt:Buffer.alloc(0),info:Buffer.from("ServerEncrypt-main")}),c=No({hash:"sha512",key:s.sharedSecret,length:32,salt:Buffer.alloc(0),info:Buffer.from("ClientEncrypt-main")});return{accessoryToControllerKey:n,controllerToAccessoryKey:c,pairingId:s.pairingId,sharedSecret:s.sharedSecret}}async#s(o,s){let n=o==="m1"?l.PV_Start:l.PV_Next,[,c]=await this.socket.exchange(n,{_pd:s,_auTy:4});if(typeof c!=="object"||c===null)throw Error("Invalid response from receiver.");return c._pd}}class lo{get api(){return this.#o}get device(){return this.#n}get socket(){return this.#s}get pairing(){return this.#c}get verify(){return this.#i}#o;#n;#s;#c;#i;constructor(o){this.#n=o,this.#s=new b(o.address,o.service.port),this.#o=new I(this),this.#c=new u(this),this.#i=new f(this)}async connect(){await this.#s.connect()}async disconnect(){await this.#s.disconnect()}}export{mo as convertAttentionState,to as MediaControlCommand,co as HidCommand,lo as CompanionLink};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basmilius/apple-companion-link",
|
|
3
3
|
"description": "Implementation of Apple's Companion Link in Node.js.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.76",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"provenance": true
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
|
-
"build": "bun -b build.ts",
|
|
28
|
+
"build": "tsc && bun -b build.ts",
|
|
29
29
|
"find": "bun find.ts",
|
|
30
30
|
"watch:test": "bun --watch test.ts"
|
|
31
31
|
},
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@basmilius/apple-common": "0.0.
|
|
43
|
+
"@basmilius/apple-common": "0.0.76",
|
|
44
|
+
"@basmilius/apple-encoding": "0.0.76"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
47
|
"@basmilius/tools": "^2.23.0",
|
package/dist/index.js.map
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/const.ts", "../src/utils.ts", "../src/api.ts", "../src/messages.ts", "../src/pairing.ts", "../src/socket.ts", "../src/verify.ts", "../src/protocol.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"export const HidCommand = {\n Up: 1,\n Down: 2,\n Left: 3,\n Right: 4,\n Menu: 5,\n Select: 6,\n Home: 7,\n VolumeUp: 8,\n VolumeDown: 9,\n Siri: 10,\n Screensaver: 11,\n Sleep: 12,\n Wake: 13,\n PlayPause: 14,\n ChannelIncrement: 15,\n ChannelDecrement: 16,\n Guide: 17,\n PageUp: 18,\n PageDown: 19\n} as const;\n\nexport const MediaControlCommand = {\n Play: 1,\n Pause: 2,\n NextTrack: 3,\n PreviousTrack: 4,\n GetVolume: 5,\n SetVolume: 6,\n SkipBy: 7,\n FastForwardBegin: 8,\n FastForwardEnd: 9,\n RewindBegin: 10,\n RewindEnd: 11,\n GetCaptionSettings: 12,\n SetCaptionSettings: 13\n} as const;\n\nexport type HidCommandKey = keyof typeof HidCommand;\nexport type MediaControlCommandKey = keyof typeof MediaControlCommand;\n",
|
|
6
|
-
"import type { AttentionState } from './types';\n\nexport function convertAttentionState(state: number): AttentionState {\n switch (state) {\n case 0x01:\n return 'asleep';\n\n case 0x02:\n return 'screensaver';\n\n case 0x03:\n return 'awake';\n\n case 0x04:\n return 'idle';\n\n default:\n return 'unknown';\n }\n}\n",
|
|
7
|
-
"import { randomInt } from 'node:crypto';\nimport { OPack, Plist, reporter, waitFor } from '@basmilius/apple-common';\nimport { HidCommand, type HidCommandKey, MediaControlCommand, type MediaControlCommandKey } from './const';\nimport { FrameType, MessageType } from './messages';\nimport type { AttentionState, ButtonPressType, LaunchableApp, UserAccount } from './types';\nimport { convertAttentionState } from './utils';\nimport type Protocol from './protocol';\nimport type Socket from './socket';\n\nexport default class CompanionLinkApi {\n get socket(): Socket {\n return this.#protocol.socket;\n }\n\n readonly #protocol: Protocol;\n\n constructor(protocol: Protocol) {\n this.#protocol = protocol;\n }\n\n async fetchMediaControlStatus(): Promise<void> {\n await this.socket.exchange(FrameType.E_OPACK, {\n _i: 'FetchMediaControlStatus',\n _t: MessageType.Request,\n _c: {}\n });\n }\n\n async fetchNowPlayingInfo(): Promise<void> {\n await this.socket.exchange(FrameType.E_OPACK, {\n _i: 'FetchCurrentNowPlayingInfoEvent',\n _t: MessageType.Request,\n _c: {}\n });\n }\n\n async fetchSupportedActions(): Promise<void> {\n await this.socket.exchange(FrameType.E_OPACK, {\n _i: 'FetchSupportedActionsEvent',\n _t: MessageType.Request,\n _c: {}\n });\n }\n\n async getAttentionState(): Promise<AttentionState> {\n const [, payload] = await this.socket.exchange(FrameType.E_OPACK, {\n _i: 'FetchAttentionState',\n _t: MessageType.Request,\n _c: {}\n });\n\n const {_c} = objectOrFail<AttentionStateResponse>(payload);\n\n return convertAttentionState(_c.state);\n }\n\n async getLaunchableApps(): Promise<LaunchableApp[]> {\n const [, payload] = await this.socket.exchange(FrameType.E_OPACK, {\n _i: 'FetchLaunchableApplicationsEvent',\n _t: MessageType.Request,\n _c: {}\n });\n\n const {_c} = objectOrFail<LaunchableAppsResponse>(payload);\n\n return Object.entries(_c).map(([bundleId, name]) => ({\n bundleId,\n name\n }));\n }\n\n async getSiriRemoteInfo(): Promise<any> {\n const [, payload] = await this.socket.exchange(FrameType.E_OPACK, {\n _i: 'FetchSiriRemoteInfo',\n _t: MessageType.Request,\n _c: {}\n });\n\n return Plist.parse(Buffer.from(payload['_c']['SiriRemoteInfoKey']).buffer);\n }\n\n async getUserAccounts(): Promise<UserAccount[]> {\n const [, payload] = await this.socket.exchange(FrameType.E_OPACK, {\n _i: 'FetchUserAccountsEvent',\n _t: MessageType.Request,\n _c: {}\n });\n\n const {_c} = objectOrFail<UserAccountsResponse>(payload);\n\n return Object.entries(_c).map(([accountId, name]) => ({\n accountId,\n name\n }));\n }\n\n async hidCommand(command: HidCommandKey, down = false): Promise<void> {\n await this.socket.exchange(FrameType.E_OPACK, {\n _i: '_hidC',\n _t: MessageType.Request,\n _c: {\n _hBtS: down ? 1 : 2,\n _hidC: HidCommand[command]\n }\n });\n }\n\n async launchApp(bundleId: string): Promise<void> {\n await this.socket.exchange(FrameType.E_OPACK, {\n _i: '_launchApp',\n _t: MessageType.Request,\n _c: {\n _bundleID: bundleId\n }\n });\n }\n\n async launchUrl(url: string): Promise<void> {\n await this.socket.exchange(FrameType.E_OPACK, {\n _i: '_launchApp',\n _t: MessageType.Request,\n _c: {\n _urlS: url\n }\n });\n }\n\n async mediaControlCommand(command: MediaControlCommandKey, content?: object): Promise<object> {\n const [, payload] = await this.socket.exchange(FrameType.E_OPACK, {\n _i: '_mcc',\n _t: MessageType.Request,\n _c: {\n _mcc: MediaControlCommand[command],\n ...(content || {})\n }\n });\n\n return objectOrFail(payload);\n }\n\n async pressButton(command: HidCommandKey, type: ButtonPressType = 'SingleTap', holdDelayMs = 500): Promise<void> {\n switch (type) {\n case 'DoubleTap':\n await this.hidCommand(command, true);\n await this.hidCommand(command, false);\n\n await this.hidCommand(command, true);\n await this.hidCommand(command, false);\n break;\n\n case 'Hold':\n await this.hidCommand(command, true);\n await waitFor(holdDelayMs);\n await this.hidCommand(command, false);\n break;\n\n case 'SingleTap':\n await this.hidCommand(command, true);\n await this.hidCommand(command, false);\n break;\n }\n }\n\n async switchUserAccount(accountId: string): Promise<void> {\n await this.socket.exchange(FrameType.E_OPACK, {\n _i: 'SwitchUserAccountEvent',\n _t: MessageType.Request,\n _c: {\n SwitchAccountID: accountId\n }\n });\n }\n\n async _subscribe(event: string, fn: (data: unknown) => void): Promise<void> {\n this.socket.on(event, fn);\n\n await this.socket.send(FrameType.E_OPACK, {\n _i: '_interest',\n _t: MessageType.Event,\n _c: {\n _regEvents: [event]\n }\n });\n }\n\n async _unsubscribe(event: string, fn?: (data: unknown) => void): Promise<void> {\n if (fn) {\n this.socket.off(event, fn);\n }\n\n await this.socket.send(FrameType.E_OPACK, {\n _i: '_interest',\n _t: MessageType.Event,\n _c: {\n _deregEvents: [event]\n }\n });\n }\n\n async _sessionStart(): Promise<object> {\n const [, payload] = await this.socket.exchange(FrameType.E_OPACK, {\n _i: '_sessionStart',\n _t: MessageType.Request,\n _c: {\n _srvT: 'com.apple.tvremoteservices',\n _sid: randomInt(0, 2 ** 32 - 1)\n }\n });\n\n return objectOrFail(payload);\n }\n\n async _systemInfo(pairingId: Buffer): Promise<object> {\n const [, payload] = await this.socket.exchange(FrameType.E_OPACK, {\n _i: '_systemInfo',\n _t: MessageType.Request,\n _c: {\n _bf: 0,\n _cf: 512,\n _clFl: 128,\n _i: 'cafecafecafe',\n _idsID: pairingId.toString(),\n _pubID: 'FF:70:79:61:74:76',\n _sf: 256,\n _sv: '170.18',\n model: 'iPhone10,6',\n name: 'Bas Companion Link'\n }\n });\n\n return objectOrFail(payload);\n }\n\n async _touchStart(): Promise<object> {\n const [, payload] = await this.socket.exchange(FrameType.E_OPACK, {\n _i: '_touchStart',\n _t: MessageType.Request,\n _c: {\n _height: OPack.float(1000.0),\n _tFl: 0,\n _width: OPack.float(1000.0)\n }\n });\n\n return objectOrFail(payload);\n }\n\n async _tvrcSessionStart(): Promise<object> {\n const [, payload] = await this.socket.exchange(FrameType.E_OPACK, {\n _i: 'TVRCSessionStart',\n _t: MessageType.Request,\n _btHP: false,\n _inUseProc: 'tvremoted',\n _c: {}\n });\n\n return objectOrFail(payload);\n }\n}\n\nfunction objectOrFail<T = object>(obj: unknown): T {\n if (typeof obj === 'object') {\n return obj as T;\n }\n\n reporter.error('Expected an object.', {obj});\n\n throw new Error('Expected an object.');\n}\n\ntype AttentionStateResponse = {\n readonly _c: {\n readonly state: number;\n };\n};\n\ntype LaunchableAppsResponse = {\n readonly _c: Record<string, string>;\n};\n\ntype UserAccountsResponse = {\n readonly _c: Record<string, string>;\n};\n",
|
|
8
|
-
"export const FrameType = {\n Unknown: 0,\n Noop: 1,\n\n PS_Start: 3,\n PS_Next: 4,\n PV_Start: 5,\n PV_Next: 6,\n\n U_OPACK: 7,\n E_OPACK: 8,\n P_OPACK: 9,\n\n PA_Request: 10,\n PA_Response: 11,\n\n SessionStartRequest: 16,\n SessionStartResponse: 17,\n SessionData: 18,\n\n FamilyIdentityRequest: 32,\n FamilyIdentityResponse: 33,\n FamilyIdentityUpdate: 34\n} as const;\n\nexport const MessageType = {\n Event: 1,\n Request: 2,\n Response: 3\n} as const;\n\nexport const OPackFrameTypes: number[] = [\n FrameType.PS_Start,\n FrameType.PS_Next,\n FrameType.PV_Start,\n FrameType.PV_Next,\n\n FrameType.U_OPACK,\n FrameType.E_OPACK,\n FrameType.P_OPACK\n];\n\nexport const PairFrameTypes: number[] = [\n FrameType.PS_Start,\n FrameType.PS_Next,\n FrameType.PV_Start,\n FrameType.PV_Next\n];\n",
|
|
9
|
-
"import { type AccessoryCredentials, type AccessoryKeys, AccessoryPair } from '@basmilius/apple-common';\nimport { FrameType } from './messages';\nimport type Socket from './socket';\nimport type Protocol from './protocol';\n\nexport default class CompanionLinkPairing {\n get internal(): AccessoryPair {\n return this.#internal;\n }\n\n get socket(): Socket {\n return this.#protocol.socket;\n }\n\n readonly #internal: AccessoryPair;\n readonly #protocol: Protocol;\n\n constructor(protocol: Protocol) {\n this.#internal = new AccessoryPair(this.#request.bind(this));\n this.#protocol = protocol;\n }\n\n async start(): Promise<void> {\n await this.#internal.start();\n }\n\n async pin(askPin: () => Promise<string>): Promise<AccessoryCredentials> {\n return this.#internal.pin(askPin);\n }\n\n async transient(): Promise<AccessoryKeys> {\n return this.#internal.transient();\n }\n\n async #request(step: 'm1' | 'm3' | 'm5', data: Buffer): Promise<Buffer> {\n const frameType = step === 'm1' ? FrameType.PS_Start : FrameType.PS_Next;\n const [, response] = await this.socket.exchange(frameType, {\n _pd: data,\n _pwTy: 1\n });\n\n if (typeof response !== 'object' || response === null) {\n throw new Error('Invalid response from receiver.');\n }\n\n return response['_pd'];\n }\n}\n",
|
|
10
|
-
"import { randomInt } from 'node:crypto';\nimport { Socket } from 'node:net';\nimport { BaseSocket, Chacha20, OPack, reporter } from '@basmilius/apple-common';\nimport { OPackFrameTypes, PairFrameTypes } from './messages';\n\nconst HEADER_BYTES = 4;\n\nexport default class CompanionLinkSocket extends BaseSocket<Record<string, [unknown]>> {\n get isConnected(): boolean {\n return this.#socket.readyState === 'open';\n }\n\n get isEncrypted(): boolean {\n return !!this.#readKey && !!this.#writeKey;\n }\n\n readonly #socket: Socket;\n readonly #queue: Record<number, Function> = {};\n #buffer: Buffer = Buffer.alloc(0);\n #readCount: number;\n #readKey?: Buffer;\n #writeCount: number;\n #writeKey?: Buffer;\n #xid: number;\n\n constructor(address: string, port: number) {\n super(address, port);\n\n this.#xid = randomInt(0, 2 ** 16);\n\n this.onClose = this.onClose.bind(this);\n this.onConnect = this.onConnect.bind(this);\n this.onData = this.onData.bind(this);\n this.onEnd = this.onEnd.bind(this);\n this.onError = this.onError.bind(this);\n\n this.#socket = new Socket();\n this.#socket.on('close', this.onClose);\n this.#socket.on('connect', this.onConnect);\n this.#socket.on('data', this.onData);\n this.#socket.on('end', this.onEnd);\n this.#socket.on('error', this.onError);\n }\n\n async connect(): Promise<void> {\n reporter.net(`Connecting to ${this.address}:${this.port}...`);\n\n return await new Promise(resolve => {\n this.#socket.connect({\n host: this.address,\n port: this.port,\n keepAlive: true\n }, resolve);\n });\n }\n\n async disconnect(): Promise<void> {\n this.#socket.destroy();\n }\n\n async enableEncryption(readKey: Buffer, writeKey: Buffer): Promise<void> {\n this.#readKey = readKey;\n this.#writeKey = writeKey;\n this.#readCount = 0;\n this.#writeCount = 0;\n }\n\n async exchange(type: number, obj: Record<string, unknown>): Promise<[number, unknown]> {\n const _x = this.#xid;\n\n return new Promise<[number, number]>((resolve, reject) => {\n if (PairFrameTypes.includes(type)) {\n this.#queue[-1] = resolve;\n } else {\n this.#queue[_x] = resolve;\n }\n\n this.send(type, obj).catch(reject);\n });\n }\n\n async send(type: number, obj: Record<string, unknown>): Promise<void> {\n const _x = this.#xid++;\n obj._x ??= OPack.sizedInt(_x, 8);\n\n let payload = Buffer.from(OPack.encode(obj));\n let payloadLength = payload.byteLength;\n\n if (this.isEncrypted && payloadLength > 0) {\n payloadLength += 16;\n }\n\n const header = Buffer.alloc(4);\n header.writeUint8(type, 0);\n header.writeUintBE(payloadLength, 1, 3);\n\n let data: Buffer;\n\n if (this.isEncrypted) {\n const nonce = Buffer.alloc(12);\n nonce.writeBigUInt64LE(BigInt(this.#writeCount++), 0);\n\n const encrypted = Chacha20.encrypt(this.#writeKey, nonce, header, payload);\n data = Buffer.concat([header, encrypted.ciphertext, encrypted.authTag]);\n } else {\n data = Buffer.concat([header, payload]);\n }\n\n reporter.raw('Send data frame', this.isEncrypted, Buffer.from(data).toString('hex'), obj);\n\n return new Promise((resolve, reject) => {\n this.#socket.write(data, err => err && reject(err));\n resolve();\n });\n }\n\n async onClose(): Promise<void> {\n await super.onClose();\n reporter.net(`Connection closed from ${this.address}:${this.port}`);\n }\n\n async onConnect(): Promise<void> {\n await super.onConnect();\n reporter.net(`Connected to ${this.address}:${this.port}`);\n }\n\n async onData(buffer: Buffer): Promise<void> {\n // reporter.raw('Received data frame', buffer.toString('hex'));\n\n this.#buffer = Buffer.concat([this.#buffer, buffer]);\n\n while (this.#buffer.byteLength >= HEADER_BYTES) {\n const header = this.#buffer.subarray(0, HEADER_BYTES);\n const payloadLength = header.readUintBE(1, 3);\n const totalLength = HEADER_BYTES + payloadLength;\n\n if (this.#buffer.byteLength < totalLength) {\n reporter.warn(`Not enough data yet, waiting on the next frame.. needed=${totalLength} available=${this.#buffer.byteLength} receivedLength=${buffer.byteLength}`);\n return;\n }\n\n reporter.raw(`Frame found length=${totalLength} availableLength=${this.#buffer.byteLength} receivedLength=${buffer.byteLength}`);\n\n const frame = Buffer.from(this.#buffer.subarray(0, totalLength));\n this.#buffer = this.#buffer.subarray(totalLength);\n\n reporter.raw(`Handle frame, ${this.#buffer.byteLength} bytes left...`);\n\n const data = await this.#decrypt(frame);\n let payload = data.subarray(4, totalLength);\n\n await this.#handle(header, payload);\n }\n }\n\n async onEnd(): Promise<void> {\n reporter.net('Connection ended');\n }\n\n async onError(err: Error): Promise<void> {\n await super.onError(err);\n reporter.error('Error received', err);\n }\n\n async #decrypt(data: Buffer): Promise<Buffer> {\n if (!this.isEncrypted) {\n return data;\n }\n\n const header = data.subarray(0, 4);\n const payloadLength = header.readUintBE(1, 3);\n\n const payload = data.subarray(4, 4 + payloadLength);\n const authTag = payload.subarray(payload.byteLength - 16);\n const ciphertext = payload.subarray(0, payload.byteLength - 16);\n\n const nonce = Buffer.alloc(12);\n nonce.writeBigUint64LE(BigInt(this.#readCount++), 0);\n\n const decrypted = Chacha20.decrypt(this.#readKey, nonce, header, ciphertext, authTag);\n\n return Buffer.concat([header, decrypted, authTag]);\n }\n\n async #handle(header: Buffer, payload: Buffer): Promise<void> {\n const type = header.readInt8();\n\n if (!OPackFrameTypes.includes(type)) {\n reporter.warn('Packet not handled, no opack frame.');\n return;\n }\n\n payload = OPack.decode(payload);\n\n reporter.raw('Decoded OPACK', {header, payload});\n\n if ('_x' in payload) {\n const _x = (payload as any)._x;\n\n if (_x in this.#queue) {\n const resolve = this.#queue[_x] ?? null;\n resolve?.([header, payload]);\n\n delete this.#queue[_x];\n } else if ('_i' in payload) {\n this.emit(payload['_i'] as string, payload['_c']);\n } else {\n // probably an event\n const content = payload['_c'];\n const keys = Object.keys(content).map(k => k.substring(0, -3));\n\n for (const key of keys) {\n this.emit(key, content[key]);\n }\n }\n } else if (this.#queue[-1]) {\n const _x = -1;\n const resolve = this.#queue[_x] ?? null;\n resolve?.([header, payload]);\n\n delete this.#queue[_x];\n } else {\n reporter.warn('No handler for message', [header, payload]);\n }\n }\n}\n",
|
|
11
|
-
"import { type AccessoryCredentials, type AccessoryKeys, AccessoryVerify, hkdf } from '@basmilius/apple-common';\nimport { FrameType } from './messages';\nimport type Protocol from './protocol';\nimport type Socket from './socket';\n\nexport default class CompanionLinkVerify {\n get socket(): Socket {\n return this.#protocol.socket;\n }\n\n readonly #internal: AccessoryVerify;\n readonly #protocol: Protocol;\n\n constructor(protocol: Protocol) {\n this.#internal = new AccessoryVerify(this.#request.bind(this));\n this.#protocol = protocol;\n }\n\n async start(credentials: AccessoryCredentials): Promise<AccessoryKeys> {\n const keys = await this.#internal.start(credentials);\n\n const accessoryToControllerKey = hkdf({\n hash: 'sha512',\n key: keys.sharedSecret,\n length: 32,\n salt: Buffer.alloc(0),\n info: Buffer.from('ServerEncrypt-main')\n });\n\n const controllerToAccessoryKey = hkdf({\n hash: 'sha512',\n key: keys.sharedSecret,\n length: 32,\n salt: Buffer.alloc(0),\n info: Buffer.from('ClientEncrypt-main')\n });\n\n return {\n accessoryToControllerKey,\n controllerToAccessoryKey,\n pairingId: keys.pairingId,\n sharedSecret: keys.sharedSecret\n };\n }\n\n async #request(step: 'm1' | 'm3' | 'm5', data: Buffer): Promise<Buffer> {\n const frameType = step === 'm1' ? FrameType.PV_Start : FrameType.PV_Next;\n const [, response] = await this.socket.exchange(frameType, {\n _pd: data,\n _auTy: 4\n });\n\n if (typeof response !== 'object' || response === null) {\n throw new Error('Invalid response from receiver.');\n }\n\n return response['_pd'];\n }\n}\n",
|
|
12
|
-
"import type { DiscoveryResult } from '@basmilius/apple-common';\nimport Api from './api';\nimport Pairing from './pairing';\nimport Socket from './socket';\nimport Verify from './verify';\n\nexport default class CompanionLink {\n get api(): Api {\n return this.#api;\n }\n\n get device(): DiscoveryResult {\n return this.#device;\n }\n\n get socket(): Socket {\n return this.#socket;\n }\n\n get pairing(): Pairing {\n return this.#pairing;\n }\n\n get verify(): Verify {\n return this.#verify;\n }\n\n readonly #api: Api;\n readonly #device: DiscoveryResult;\n readonly #socket: Socket;\n readonly #pairing: Pairing;\n readonly #verify: Verify;\n\n constructor(device: DiscoveryResult) {\n this.#device = device;\n this.#socket = new Socket(device.address, device.service.port);\n this.#api = new Api(this);\n this.#pairing = new Pairing(this);\n this.#verify = new Verify(this);\n }\n\n async connect(): Promise<void> {\n await this.#socket.connect();\n }\n\n async disconnect(): Promise<void> {\n await this.#socket.disconnect();\n }\n}\n"
|
|
13
|
-
],
|
|
14
|
-
"mappings": "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",
|
|
15
|
-
"debugId": "E00B066B0AF3EB3A64756E2164756E21",
|
|
16
|
-
"names": []
|
|
17
|
-
}
|