librespot/src/audio_key.rs

64 lines
1.6 KiB
Rust
Raw Normal View History

2015-06-23 14:38:29 +00:00
use std::collections::HashMap;
use std::sync::{mpsc, Future};
2015-06-23 14:38:29 +00:00
use std::io::{Cursor, Write};
use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
use readall::ReadAllExt;
use util::{SpotifyId, FileId, IgnoreExt};
use session::Session;
use connection::PacketHandler;
2015-06-23 14:38:29 +00:00
pub type AudioKey = [u8; 16];
type AudioKeyId = u32;
2015-06-23 14:38:29 +00:00
pub struct AudioKeyManager {
next_seq: AudioKeyId,
callbacks: HashMap<AudioKeyId, mpsc::Sender<AudioKey>>,
2015-06-23 14:38:29 +00:00
}
impl AudioKeyManager {
pub fn new() -> AudioKeyManager {
AudioKeyManager {
2015-06-23 14:38:29 +00:00
next_seq: 1,
callbacks: HashMap::new(),
}
2015-06-23 14:38:29 +00:00
}
pub fn request(&mut self, session: &Session, track: SpotifyId, file: FileId)
-> Future<AudioKey> {
let (tx, rx) = mpsc::channel();
2015-06-23 14:38:29 +00:00
let seq = self.next_seq;
self.next_seq += 1;
let mut data : Vec<u8> = Vec::new();
data.write(&file).unwrap();
data.write(&track.to_raw()).unwrap();
2015-06-23 14:38:29 +00:00
data.write_u32::<BigEndian>(seq).unwrap();
data.write_u16::<BigEndian>(0x0000).unwrap();
session.send_packet(0xc, &data).unwrap();
self.callbacks.insert(seq, tx);
2015-06-23 14:38:29 +00:00
Future::from_receiver(rx)
2015-06-23 14:38:29 +00:00
}
}
2015-06-23 14:38:29 +00:00
impl PacketHandler for AudioKeyManager {
fn handle(&mut self, cmd: u8, data: Vec<u8>) {
assert_eq!(cmd, 0xd);
2015-06-23 14:38:29 +00:00
let mut data = Cursor::new(data);
2015-06-23 14:38:29 +00:00
let seq = data.read_u32::<BigEndian>().unwrap();
let mut key = [0u8; 16];
data.read_all(&mut key).unwrap();
match self.callbacks.remove(&seq) {
Some(callback) => callback.send(key).ignore(),
2015-06-23 14:38:29 +00:00
None => ()
};
}
}