270 lines
5.9 KiB
C++
270 lines
5.9 KiB
C++
#include "WifiDevice.h"
|
|
#include "api.h"
|
|
#include "device.h"
|
|
#include "nu/ns_wc.h"
|
|
#include "resource.h"
|
|
#include "Pair.h"
|
|
#include "images.h"
|
|
#include "modelInfo.h"
|
|
#include "SongListDownloader.h"
|
|
#include <strsafe.h>
|
|
|
|
WifiDevice::WifiDevice(const char *root_url, const DeviceInfo *in_device_info)
|
|
: url(strdup(root_url))
|
|
{
|
|
DeviceInfo_Copy(&device_info, in_device_info);
|
|
InitializeCriticalSection(®ister_lock);
|
|
dead=0;
|
|
connect_active=false;
|
|
pmp_device=0;
|
|
StringCbPrintfA(id_string, sizeof(id_string), "%016I64x", device_info.id);
|
|
if (IsPaired(device_info.id))
|
|
{
|
|
char full_url[256] = {0};
|
|
StringCbPrintfA(full_url, sizeof(full_url), "%s/library", url);
|
|
WAC_API_DOWNLOADMANAGER->DownloadEx(full_url, new SongListDownloader(url, this), api_downloadManager::DOWNLOADEX_CALLBACK);
|
|
}
|
|
else
|
|
{
|
|
ifc_device *device = this;
|
|
AGAVE_API_DEVICEMANAGER->DeviceRegister(&device, 1);
|
|
}
|
|
}
|
|
|
|
WifiDevice::~WifiDevice()
|
|
{
|
|
DeleteCriticalSection(®ister_lock);
|
|
}
|
|
|
|
/* ifc_device stuff */
|
|
int WifiDevice::QueryInterface(GUID interface_guid, void **object)
|
|
{
|
|
if (interface_guid == IFC_Device)
|
|
{
|
|
AddRef();
|
|
*object = (ifc_device *)this;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
const char *WifiDevice::GetName()
|
|
{
|
|
return id_string;
|
|
}
|
|
|
|
HRESULT WifiDevice::GetDisplayName(wchar_t *buffer, size_t bufferSize)
|
|
{
|
|
StringCchCopyW(buffer, bufferSize, device_info.name);
|
|
return 0;
|
|
}
|
|
|
|
const char *WifiDevice::GetType()
|
|
{
|
|
return "portable";
|
|
}
|
|
|
|
const char *WifiDevice::GetConnection()
|
|
{
|
|
return "wifi";
|
|
}
|
|
|
|
extern ifc_devicesupportedcommandenum *command_enum;
|
|
extern ifc_devicesupportedcommandstore *command_store;
|
|
extern ifc_deviceeventmanager *device_event_manager;
|
|
|
|
HRESULT WifiDevice::EnumerateCommands(ifc_devicesupportedcommandenum **enumerator, DeviceCommandContext context)
|
|
{
|
|
if (connect_active)
|
|
return E_NOTIMPL;
|
|
|
|
return command_store->Enumerate(enumerator);
|
|
}
|
|
|
|
HRESULT WifiDevice::SendCommand(const char *command, HWND hostWindow, ULONG_PTR param)
|
|
{
|
|
if (!strcmp(command, "attach"))
|
|
{
|
|
return Attach(hostWindow);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL WifiDevice::GetAttached()
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
HRESULT WifiDevice::Attach(HWND hostWindow)
|
|
{
|
|
if (!connect_active)
|
|
{
|
|
connect_active = true;
|
|
device_event_manager->Notify_ActivityStarted(this, &connect_activity);
|
|
|
|
char full_url[256] = {0};
|
|
StringCbPrintfA(full_url, sizeof(full_url), "%s/pair", url);
|
|
WAC_API_DOWNLOADMANAGER->DownloadEx(full_url, new PairDownloader(this), api_downloadManager::DOWNLOADEX_CALLBACK);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WifiDevice::Detach(HWND hostWindow)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WifiDevice::Advise(ifc_deviceevent *handler)
|
|
{
|
|
return device_event_manager->Advise(handler);
|
|
}
|
|
|
|
HRESULT WifiDevice::Unadvise(ifc_deviceevent *handler)
|
|
{
|
|
return device_event_manager->Unadvise(handler);
|
|
}
|
|
|
|
HRESULT WifiDevice::GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height)
|
|
{
|
|
return ModelInfo_GetIconPath(device_info.modelInfo, width, height, buffer, bufferSize, TRUE);
|
|
}
|
|
|
|
void WifiDevice::OnPaired()
|
|
{
|
|
char full_url[256] = {0};
|
|
StringCbPrintfA(full_url, sizeof(full_url), "%s/library", url);
|
|
WAC_API_DOWNLOADMANAGER->DownloadEx(full_url, new SongListDownloader(url, this), api_downloadManager::DOWNLOADEX_CALLBACK);
|
|
SetPaired(device_info.id, true);
|
|
}
|
|
|
|
void WifiDevice::OnConnected(TemplateDevice *device)
|
|
{
|
|
EnterCriticalSection(®ister_lock);
|
|
pmp_device = device;
|
|
connect_active = false;
|
|
device_event_manager->Notify_ActivityFinished(this, &connect_activity);
|
|
AGAVE_API_DEVICEMANAGER->DeviceUnregister(id_string);
|
|
// if we disconnected/timed out on the listen server while connecting, go ahead and close the device out
|
|
if (dead && pmp_device)
|
|
{
|
|
pmp_device->CloseAsync();
|
|
pmp_device = 0;
|
|
}
|
|
LeaveCriticalSection(®ister_lock);
|
|
}
|
|
|
|
void WifiDevice::OnDisconnect()
|
|
{
|
|
// TODO: might actually need a crit sec here
|
|
EnterCriticalSection(®ister_lock);
|
|
dead=1;
|
|
if (pmp_device)
|
|
{
|
|
pmp_device->CloseAsync();
|
|
pmp_device = 0;
|
|
}
|
|
else
|
|
{
|
|
AGAVE_API_DEVICEMANAGER->DeviceUnregister(id_string);
|
|
}
|
|
LeaveCriticalSection(®ister_lock);
|
|
}
|
|
|
|
void WifiDevice::OnConnectionFailed()
|
|
{
|
|
EnterCriticalSection(®ister_lock);
|
|
delete pmp_device;
|
|
pmp_device = 0;
|
|
ifc_device *device = NULL;
|
|
bool device_exist = false;
|
|
|
|
// see if we're already registered (e.g. we started in unpaired state)
|
|
if (AGAVE_API_DEVICEMANAGER->DeviceFind(id_string, &device) == S_OK)
|
|
{
|
|
if (device == this)
|
|
device_exist = true;
|
|
|
|
device->Release();
|
|
}
|
|
|
|
if (device_exist)
|
|
{ // if we are, then notify about activity being done
|
|
connect_active = false;
|
|
device_event_manager->Notify_ActivityFinished(this, &connect_activity);
|
|
}
|
|
else if (!dead)
|
|
{ // if we weren't registered, we thought we were paired but failed
|
|
device = this;
|
|
AGAVE_API_DEVICEMANAGER->DeviceRegister(&device, 1);
|
|
}
|
|
|
|
|
|
LeaveCriticalSection(®ister_lock);
|
|
}
|
|
|
|
HRESULT WifiDevice::GetActivity(ifc_deviceactivity **activity)
|
|
{
|
|
if (connect_active)
|
|
{
|
|
*activity = &connect_activity;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
HRESULT WifiDevice::GetTotalSpace(uint64_t *size)
|
|
{
|
|
#if 0
|
|
if (device_info.total_space)
|
|
{
|
|
*size = device_info.total_space;
|
|
return S_OK;
|
|
}
|
|
#endif
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT WifiDevice::GetUsedSpace(uint64_t *size)
|
|
{
|
|
#if 0
|
|
if (device_info.used_space)
|
|
{
|
|
*size = device_info.used_space;
|
|
return S_OK;
|
|
}
|
|
#endif
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT WifiDevice::GetModel(wchar_t *buffer, size_t bufferSize)
|
|
{
|
|
return ModelInfo_CopyDisplayName(device_info.modelInfo, buffer, bufferSize);
|
|
}
|
|
|
|
#define CBCLASS WifiDevice
|
|
START_DISPATCH;
|
|
CB(QUERYINTERFACE, QueryInterface);
|
|
CB(API_GETNAME, GetName);
|
|
CB(API_GETICON, GetIcon);
|
|
CB(API_GETDISPLAYNAME, GetDisplayName);
|
|
CB(API_GETTOTALSPACE, GetTotalSpace);
|
|
CB(API_GETUSEDSPACE, GetUsedSpace);
|
|
CB(API_GETTYPE, GetType);
|
|
CB(API_GETCONNECTION, GetConnection);
|
|
CB(API_ENUMERATECOMMANDS, EnumerateCommands);
|
|
CB(API_SENDCOMMAND, SendCommand);
|
|
CB(API_GETATTACHED, GetAttached);
|
|
CB(API_ATTACH, Attach);
|
|
CB(API_DETACH, Detach);
|
|
CB(API_GETACTIVITY, GetActivity);
|
|
CB(API_ADVISE, Advise);
|
|
CB(API_UNADVISE, Unadvise);
|
|
CB(API_GETMODEL, GetModel);
|
|
REFERENCE_COUNTED;
|
|
END_DISPATCH;
|