@@ -36,10 +36,12 @@ pub struct Config {
3636 pub name : Cow < ' static , str > ,
3737 pub device_type : DeviceType ,
3838 pub device_id : String ,
39+ pub client_id : String ,
3940}
4041
4142struct RequestHandler {
4243 config : Config ,
44+ username : Option < String > ,
4345 keys : DhLocalKeys ,
4446 tx : mpsc:: UnboundedSender < Credentials > ,
4547}
@@ -50,6 +52,7 @@ impl RequestHandler {
5052
5153 let discovery = Self {
5254 config,
55+ username : None ,
5356 keys : DhLocalKeys :: random ( & mut rand:: thread_rng ( ) ) ,
5457 tx,
5558 } ;
@@ -60,24 +63,45 @@ impl RequestHandler {
6063 fn handle_get_info ( & self ) -> Response < hyper:: Body > {
6164 let public_key = base64:: encode ( & self . keys . public_key ( ) ) ;
6265 let device_type: & str = self . config . device_type . into ( ) ;
66+ let mut active_user = String :: new ( ) ;
67+ if let Some ( username) = & self . username {
68+ active_user = username. to_string ( ) ;
69+ }
6370
71+ // See: https://developer.spotify.com/documentation/commercial-hardware/implementation/guides/zeroconf/
6472 let body = json ! ( {
6573 "status" : 101 ,
66- "statusString" : "ERROR- OK" ,
74+ "statusString" : "OK" ,
6775 "spotifyError" : 0 ,
68- "version" : crate :: core:: version:: SEMVER ,
76+ // departing from the Spotify documentation, Google Cast uses "5.0.0"
77+ "version" : "2.9.0" ,
6978 "deviceID" : ( self . config. device_id) ,
79+ "deviceType" : ( device_type) ,
7080 "remoteName" : ( self . config. name) ,
71- "activeUser" : "" ,
81+ // valid value seen in the wild : "empty"
7282 "publicKey" : ( public_key) ,
73- "deviceType" : ( device_type) ,
74- "libraryVersion" : crate :: core:: version:: SEMVER ,
75- "accountReq" : "PREMIUM" ,
7683 "brandDisplayName" : "librespot" ,
7784 "modelDisplayName" : "librespot" ,
78- "resolverVersion" : "0" ,
85+ "libraryVersion" : crate :: core:: version:: SEMVER ,
86+ "resolverVersion" : "1" ,
7987 "groupStatus" : "NONE" ,
80- "voiceSupport" : "NO" ,
88+ // valid value documented & seen in the wild: "accesstoken"
89+ // Using it will cause clients to fail to connect.
90+ "tokenType" : "default" ,
91+ "clientID" : ( self . config. client_id) ,
92+ "productID" : 0 ,
93+ // Other known scope: client-authorization-universal
94+ // Comma-separated.
95+ "scope" : "streaming" ,
96+ "availability" : "" ,
97+ "supported_drm_media_formats" : [ ] ,
98+ // TODO: bitmask but what are the flags?
99+ "supported_capabilities" : 1 ,
100+ // undocumented but should still work
101+ "accountReq" : "PREMIUM" ,
102+ "activeUser" : active_user,
103+ // others seen-in-the-wild:
104+ // - "deviceAPI_isGroup": False
81105 } )
82106 . to_string ( ) ;
83107
@@ -162,7 +186,7 @@ impl RequestHandler {
162186 let result = json ! ( {
163187 "status" : 101 ,
164188 "spotifyError" : 0 ,
165- "statusString" : "ERROR- OK"
189+ "statusString" : "OK" ,
166190 } ) ;
167191
168192 let body = result. to_string ( ) ;
0 commit comments