WifiDevice.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #include "WifiDevice.h"
  2. #include "api.h"
  3. #include "device.h"
  4. #include "nu/ns_wc.h"
  5. #include "resource.h"
  6. #include "Pair.h"
  7. #include "images.h"
  8. #include "modelInfo.h"
  9. #include "SongListDownloader.h"
  10. #include <strsafe.h>
  11. WifiDevice::WifiDevice(const char *root_url, const DeviceInfo *in_device_info)
  12. : url(strdup(root_url))
  13. {
  14. DeviceInfo_Copy(&device_info, in_device_info);
  15. InitializeCriticalSection(&register_lock);
  16. dead=0;
  17. connect_active=false;
  18. pmp_device=0;
  19. StringCbPrintfA(id_string, sizeof(id_string), "%016I64x", device_info.id);
  20. if (IsPaired(device_info.id))
  21. {
  22. char full_url[256] = {0};
  23. StringCbPrintfA(full_url, sizeof(full_url), "%s/library", url);
  24. WAC_API_DOWNLOADMANAGER->DownloadEx(full_url, new SongListDownloader(url, this), api_downloadManager::DOWNLOADEX_CALLBACK);
  25. }
  26. else
  27. {
  28. ifc_device *device = this;
  29. AGAVE_API_DEVICEMANAGER->DeviceRegister(&device, 1);
  30. }
  31. }
  32. WifiDevice::~WifiDevice()
  33. {
  34. DeleteCriticalSection(&register_lock);
  35. }
  36. /* ifc_device stuff */
  37. int WifiDevice::QueryInterface(GUID interface_guid, void **object)
  38. {
  39. if (interface_guid == IFC_Device)
  40. {
  41. AddRef();
  42. *object = (ifc_device *)this;
  43. return 0;
  44. }
  45. return 1;
  46. }
  47. const char *WifiDevice::GetName()
  48. {
  49. return id_string;
  50. }
  51. HRESULT WifiDevice::GetDisplayName(wchar_t *buffer, size_t bufferSize)
  52. {
  53. StringCchCopyW(buffer, bufferSize, device_info.name);
  54. return 0;
  55. }
  56. const char *WifiDevice::GetType()
  57. {
  58. return "portable";
  59. }
  60. const char *WifiDevice::GetConnection()
  61. {
  62. return "wifi";
  63. }
  64. extern ifc_devicesupportedcommandenum *command_enum;
  65. extern ifc_devicesupportedcommandstore *command_store;
  66. extern ifc_deviceeventmanager *device_event_manager;
  67. HRESULT WifiDevice::EnumerateCommands(ifc_devicesupportedcommandenum **enumerator, DeviceCommandContext context)
  68. {
  69. if (connect_active)
  70. return E_NOTIMPL;
  71. return command_store->Enumerate(enumerator);
  72. }
  73. HRESULT WifiDevice::SendCommand(const char *command, HWND hostWindow, ULONG_PTR param)
  74. {
  75. if (!strcmp(command, "attach"))
  76. {
  77. return Attach(hostWindow);
  78. }
  79. return 0;
  80. }
  81. BOOL WifiDevice::GetAttached()
  82. {
  83. return FALSE;
  84. }
  85. HRESULT WifiDevice::Attach(HWND hostWindow)
  86. {
  87. if (!connect_active)
  88. {
  89. connect_active = true;
  90. device_event_manager->Notify_ActivityStarted(this, &connect_activity);
  91. char full_url[256] = {0};
  92. StringCbPrintfA(full_url, sizeof(full_url), "%s/pair", url);
  93. WAC_API_DOWNLOADMANAGER->DownloadEx(full_url, new PairDownloader(this), api_downloadManager::DOWNLOADEX_CALLBACK);
  94. }
  95. return S_OK;
  96. }
  97. HRESULT WifiDevice::Detach(HWND hostWindow)
  98. {
  99. return S_OK;
  100. }
  101. HRESULT WifiDevice::Advise(ifc_deviceevent *handler)
  102. {
  103. return device_event_manager->Advise(handler);
  104. }
  105. HRESULT WifiDevice::Unadvise(ifc_deviceevent *handler)
  106. {
  107. return device_event_manager->Unadvise(handler);
  108. }
  109. HRESULT WifiDevice::GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height)
  110. {
  111. return ModelInfo_GetIconPath(device_info.modelInfo, width, height, buffer, bufferSize, TRUE);
  112. }
  113. void WifiDevice::OnPaired()
  114. {
  115. char full_url[256] = {0};
  116. StringCbPrintfA(full_url, sizeof(full_url), "%s/library", url);
  117. WAC_API_DOWNLOADMANAGER->DownloadEx(full_url, new SongListDownloader(url, this), api_downloadManager::DOWNLOADEX_CALLBACK);
  118. SetPaired(device_info.id, true);
  119. }
  120. void WifiDevice::OnConnected(TemplateDevice *device)
  121. {
  122. EnterCriticalSection(&register_lock);
  123. pmp_device = device;
  124. connect_active = false;
  125. device_event_manager->Notify_ActivityFinished(this, &connect_activity);
  126. AGAVE_API_DEVICEMANAGER->DeviceUnregister(id_string);
  127. // if we disconnected/timed out on the listen server while connecting, go ahead and close the device out
  128. if (dead && pmp_device)
  129. {
  130. pmp_device->CloseAsync();
  131. pmp_device = 0;
  132. }
  133. LeaveCriticalSection(&register_lock);
  134. }
  135. void WifiDevice::OnDisconnect()
  136. {
  137. // TODO: might actually need a crit sec here
  138. EnterCriticalSection(&register_lock);
  139. dead=1;
  140. if (pmp_device)
  141. {
  142. pmp_device->CloseAsync();
  143. pmp_device = 0;
  144. }
  145. else
  146. {
  147. AGAVE_API_DEVICEMANAGER->DeviceUnregister(id_string);
  148. }
  149. LeaveCriticalSection(&register_lock);
  150. }
  151. void WifiDevice::OnConnectionFailed()
  152. {
  153. EnterCriticalSection(&register_lock);
  154. delete pmp_device;
  155. pmp_device = 0;
  156. ifc_device *device = NULL;
  157. bool device_exist = false;
  158. // see if we're already registered (e.g. we started in unpaired state)
  159. if (AGAVE_API_DEVICEMANAGER->DeviceFind(id_string, &device) == S_OK)
  160. {
  161. if (device == this)
  162. device_exist = true;
  163. device->Release();
  164. }
  165. if (device_exist)
  166. { // if we are, then notify about activity being done
  167. connect_active = false;
  168. device_event_manager->Notify_ActivityFinished(this, &connect_activity);
  169. }
  170. else if (!dead)
  171. { // if we weren't registered, we thought we were paired but failed
  172. device = this;
  173. AGAVE_API_DEVICEMANAGER->DeviceRegister(&device, 1);
  174. }
  175. LeaveCriticalSection(&register_lock);
  176. }
  177. HRESULT WifiDevice::GetActivity(ifc_deviceactivity **activity)
  178. {
  179. if (connect_active)
  180. {
  181. *activity = &connect_activity;
  182. return S_OK;
  183. }
  184. else
  185. {
  186. return E_FAIL;
  187. }
  188. }
  189. HRESULT WifiDevice::GetTotalSpace(uint64_t *size)
  190. {
  191. #if 0
  192. if (device_info.total_space)
  193. {
  194. *size = device_info.total_space;
  195. return S_OK;
  196. }
  197. #endif
  198. return E_NOTIMPL;
  199. }
  200. HRESULT WifiDevice::GetUsedSpace(uint64_t *size)
  201. {
  202. #if 0
  203. if (device_info.used_space)
  204. {
  205. *size = device_info.used_space;
  206. return S_OK;
  207. }
  208. #endif
  209. return E_NOTIMPL;
  210. }
  211. HRESULT WifiDevice::GetModel(wchar_t *buffer, size_t bufferSize)
  212. {
  213. return ModelInfo_CopyDisplayName(device_info.modelInfo, buffer, bufferSize);
  214. }
  215. #define CBCLASS WifiDevice
  216. START_DISPATCH;
  217. CB(QUERYINTERFACE, QueryInterface);
  218. CB(API_GETNAME, GetName);
  219. CB(API_GETICON, GetIcon);
  220. CB(API_GETDISPLAYNAME, GetDisplayName);
  221. CB(API_GETTOTALSPACE, GetTotalSpace);
  222. CB(API_GETUSEDSPACE, GetUsedSpace);
  223. CB(API_GETTYPE, GetType);
  224. CB(API_GETCONNECTION, GetConnection);
  225. CB(API_ENUMERATECOMMANDS, EnumerateCommands);
  226. CB(API_SENDCOMMAND, SendCommand);
  227. CB(API_GETATTACHED, GetAttached);
  228. CB(API_ATTACH, Attach);
  229. CB(API_DETACH, Detach);
  230. CB(API_GETACTIVITY, GetActivity);
  231. CB(API_ADVISE, Advise);
  232. CB(API_UNADVISE, Unadvise);
  233. CB(API_GETMODEL, GetModel);
  234. REFERENCE_COUNTED;
  235. END_DISPATCH;