1 if(Garmin == undefined){ 2 /** 3 *@namespace Garmin The Garmin namespace object. 4 */ 5 var Garmin = {}; 6 } 7 /** Copyright © 2007-2011 Garmin Ltd. or its subsidiaries. 8 * 9 * Licensed under the Apache License, Version 2.0 (the 'License') 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an 'AS IS' BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 * @fileOverview Garmin.DevicePlugin wraps the Garmin ActiveX/Netscape plugin that should be installed on your machine in order to talk to a Garmin Device.<br/> 22 * The plugin is available for download from http://www.garmin.com/support/download_details.jsp?id=3608 23 * More information is available about this plugin from http://www.garmin.com/products/communicator/ 24 * @version 1.9 25 */ 26 27 /** 28 * Wraps the ActiveX/Netscape plugin that should be installed on your machine in order to talk to a Garmin Device. 29 * The Garmin Communicator Plugin is available for download <a href="http://www.garmin.com/support/download_details.jsp?id=3608">here</a><br/> 30 * More information is available about the plugin <a href="http://www.garmin.com/products/communicator/">here</a><br/><br/> 31 * This api provides a set of functions to accomplish the following tasks with a Garmin Device: 32 * <br/> 33 * <br/> 1) Unlocking devices allowing them to be found and accessed. 34 * <br/> 2) Finding avaliable devices plugged into this machine. 35 * <br/> 3) Reading from the device. 36 * <br/> 4) Writing to the device. 37 * <br/> 5) Getting messages, getting transfer status/progress and version information from the device. 38 * <br/><br/> 39 * Note that XML schemas <a href=http://www.garmin.com/xmlschemas/GarminPluginAPIV1.xsd>GarminPluginAPIV1</a> and 40 * <a href=http://www.garmin.com/xmlschemas/DeviceDownloadV1.xsd>DeviceDownloadV1</a> define XML input and output throughout this API.<br/> 41 * 42 * @class Garmin.DevicePlugin 43 * @constructor 44 * @param pluginElement element that references the Garmin GPS Control Web Plugin that should be installed. 45 * @return a new Garmin.DevicePlugin 46 * 47 * @requires Prototype 48 */ 49 50 Garmin.DevicePlugin = function(pluginElement){}; //just here for jsdoc 51 Garmin.DevicePlugin = Class.create(); 52 Garmin.DevicePlugin.prototype = { 53 54 /** Constructor. 55 * @private 56 */ 57 initialize: function(pluginElement) { 58 this.plugin = pluginElement; 59 this.unlocked = false; 60 //console.debug("DevicePlugin constructor supportsFitnessWrite="+this.supportsFitnessWrite) 61 }, 62 63 /** Unlocks the GpsControl object to be used at the given web address. 64 * More than one set of path-key pairs my be passed in, for example: 65 * ['http://myDomain.com/', 'xxx','http://www.myDomain.com/', 'yyy'] 66 * See documentation site for more info on getting a key. <br/> 67 * <br/> 68 * Minimum plugin version 2.0.0.4 69 * 70 * @param pathKeyPairsArray {Array}- baseURL and key pairs. 71 * @type Boolean 72 * @return true if successfully unlocked or undefined otherwise 73 */ 74 unlock: function(pathKeyPairsArray) { 75 var len = pathKeyPairsArray ? pathKeyPairsArray.length / 2 : 0; 76 for(var i=0;i<len;i++) { 77 if (this.plugin.Unlock(pathKeyPairsArray[i*2], pathKeyPairsArray[i*2+1])){ 78 this.unlocked = true; 79 return this.unlocked; 80 } 81 } 82 83 // Unlock codes for local development 84 this.tryUnlock = this.plugin.Unlock("file:///","cb1492ae040612408d87cc53e3f7ff3c") 85 || this.plugin.Unlock("http://localhost","45517b532362fc3149e4211ade14c9b2") 86 || this.plugin.Unlock("http://127.0.0.1","40cd4860f7988c53b15b8491693de133"); 87 88 this.unlocked = !this.plugin.Locked; 89 90 return this.unlocked; 91 }, 92 93 /** Returns true if the plug-in is unlocked. 94 */ 95 isUnlocked: function() { 96 return this.unlocked; 97 }, 98 99 /** 100 * Check to see if a property (function or field) is defined for an object. 101 * This function is reliable for native and host objects. 102 * @param object {Object} - the object to test. 103 * @param propertyName {String} - name of the property to test. 104 * @type Boolean 105 * @return true - if property is defined, False otherwise. 106 */ 107 _propertyExists: function( object, property ) { 108 //tweaked version of Michaux's detection function: 109 //http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting 110 var isProperty = false; 111 var theType = typeof object[property]; 112 if( theType != 'undefined' ) { 113 isProperty = true; 114 } 115 else { 116 try { 117 // This test would error for ActiveX but 118 // those test will have returned above 119 // because typeof result will have been 120 // 'unknown'. 121 if( object[property] ) { 122 isProperty = true; 123 } 124 } 125 catch (e) {} 126 } 127 return isProperty; 128 }, 129 130 /** Lazy-logic accessor to fitness write support var. 131 * This is used to detect whether the user's installed plugin supports fitness writing. 132 * Fitness writing capability has a minimum requirement of plugin version 2.2.0.1. 133 * This should NOT be called until the plug-in has been unlocked. 134 */ 135 getSupportsFitnessWrite: function() { 136 return this._propertyExists(this.plugin, "StartWriteFitnessData"); 137 }, 138 139 /** Lazy-logic accessor to fitness write support var. 140 * This is used to detect whether the user's installed plugin supports fitness directory reading, 141 * which has a minimum requirement of plugin version 2.2.0.2. 142 * This should NOT be called until the plug-in has been unlocked. 143 */ 144 getSupportsFitnessDirectoryRead: function() { 145 return this._propertyExists(this.plugin, "StartReadFitnessDirectory"); 146 }, 147 148 /** Lazy-logic accessor to FIT read support var. 149 * This is used to detect whether the user's installed plugin supports FIT directory reading, 150 * which has a minimum requirement of plugin version 2.8.1.0. 151 * This should NOT be called until the plug-in has been unlocked. 152 */ 153 getSupportsFitDirectoryRead: function() { 154 return this._propertyExists(this.plugin, "StartReadFITDirectory"); 155 }, 156 157 /** Lazy-logic accessor to fitness read compressed support var. 158 * This is used to detect whether the user's installed plugin supports fitness reading in compressed format, 159 * which has a minimum requirement of plugin version 2.2.0.2. 160 * This should NOT be called until the plug-in has been unlocked. 161 */ 162 getSupportsFitnessReadCompressed: function() { 163 return this._propertyExists(this.plugin, "TcdXmlz" ); 164 }, 165 166 /** This is used to detect whether the user's installed plugin supports readable file listing. 167 * Readable file listing has a minimum requirement of plugin version 2.8.1.0. 168 * This should NOT be called until the plug-in has been unlocked. 169 */ 170 getSupportsReadableFileListing: function() { 171 return this._propertyExists(this.plugin, "StartReadableFileListing"); 172 }, 173 174 /** Initiates a find Gps devices action on the plugin. 175 * Poll with finishFindDevices to determine when the plugin has completed this action. 176 * Use getDeviceXmlString to inspect xml contents for and array of Device nodes.<br/> 177 * <br/> 178 * Minimum plugin version 2.0.0.4 179 * 180 * @see #finishFindDevices 181 * @see #cancelFindDevices 182 */ 183 startFindDevices: function() { 184 this.plugin.StartFindDevices(); 185 }, 186 187 /** Cancels the current find devices interaction. <br/> 188 * <br/> 189 * Minimum plugin version 2.0.0.4 190 * 191 * @see #startFindDevices 192 * @see #finishFindDevices 193 */ 194 cancelFindDevices: function() { 195 this.plugin.CancelFindDevices(); 196 }, 197 198 /** Poll - with this function to determine completion of startFindDevices. Used after 199 * the call to startFindDevices(). <br/> 200 * <br/> 201 * Minimum plugin version 2.0.0.4 202 * 203 * @type Boolean 204 * @return Returns true if completed finding devices otherwise false. 205 * @see #startFindDevices 206 * @see #cancelFindDevices 207 */ 208 finishFindDevices: function() { 209 return this.plugin.FinishFindDevices(); 210 }, 211 212 /** Returns information about the number of devices connected to this machine as 213 * well as the names of those devices. Refer to the Devices_t element in the 214 * <a href="http://www.garmin.com/xmlschemas/GarminPluginAPIV1.xsd">GarminPluginAPIV1 schema</a> 215 * for what is included. 216 * The xml returned should contain a 'Device' element with 'DisplayName' and 'Number' 217 * if there is a device actually connected. <br/> 218 * <br/> 219 * Minimum plugin version 2.0.0.4 220 * 221 * @type String 222 * @return Xml string with detailed device info 223 * @see #getDeviceDescriptionXml 224 */ 225 getDevicesXml: function(){ 226 return this.plugin.DevicesXmlString(); 227 }, 228 229 /** Returns information about the specified Device indicated by the device Number. 230 * See the getDevicesXml function to get the actual deviceNumber assigned. 231 * Refer to the 232 * <a href="http://developer.garmin.com/schemas/device/v2/xmlspy/index.html#Link04DDFE88">Devices_t</a> 233 * element in the Device XML schema for what is included in the XML. <br/> 234 * <br/> 235 * Minimum plugin version 2.0.0.4 236 * 237 * @param deviceNumber {Number} Assigned by the plugin, see getDevicesXml for 238 * assignment of that number. 239 * @type String 240 * @return Xml string with detailed device info 241 * @see #getDevicesXml for device number assignment 242 */ 243 getDeviceDescriptionXml: function(deviceNumber){ 244 return this.plugin.DeviceDescription(deviceNumber); 245 }, 246 247 /**Returns the number, assigned by plugin, of the parent device.<br/> 248 * If the device has no parent, -1 is returned.<br/> 249 * Minimum plugin version 2.9.2.5 250 * 251 * @param deviceNumber {Number} Assigned by the plugin 252 * @returns {Number} Parent device's assigned number. -1 if the device has no parent. 253 * @see #getDevicesXml for device number assignment 254 */ 255 getParentDevice: function(deviceNumber) { 256 if( !this.checkPluginVersionSupport([2,9,2,5]) ) 257 { 258 throw new Error("Your Communicator Plug-in version (" + this.getPluginVersionString() + ") does not support device hierarchy (getParentDevice)"); 259 } 260 return this.plugin.ParentDevice(deviceNumber); 261 }, 262 263 // Read Methods 264 265 /** Initiates the read from the gps device conneted. Use finishReadFromGps and getGpsProgressXml to 266 * determine when the plugin is done with this operation. Also, use getGpsXml to extract the 267 * actual data from the device. <br/> 268 * <br/> 269 * Minimum plugin version 2.0.0.4 270 * 271 * @param deviceNumber {Number} assigned by the plugin, see getDevicesXml for 272 * assignment of that number. 273 * @see #finishReadFromGps 274 * @see #cancelReadFromGps 275 * @see #getDevicesXml for device number assignment 276 */ 277 startReadFromGps: function(deviceNumber) { 278 this.plugin.StartReadFromGps( deviceNumber ); 279 }, 280 281 /** Indicates the status of the read process. It will return an integer 282 * know as the completion state. The purpose is to show the 283 * user information about what is happening to the plugin while it 284 * is servicing your request. Used after startReadFromGps(). <br/> 285 * <br/> 286 * Minimum plugin version 2.0.0.4 287 * 288 * @type Number 289 * @return Completion state - The completion state can be one of the following: <br/> 290 * <br/> 291 * 0 = idle <br/> 292 * 1 = working <br/> 293 * 2 = waiting <br/> 294 * 3 = finished <br/> 295 * @see #startReadFromGps 296 * @see #cancelReadFromGps 297 */ 298 finishReadFromGps: function() { 299 return this.plugin.FinishReadFromGps(); 300 }, 301 302 /** Cancels the current read from the device. <br/> 303 * <br/> 304 * Minimum plugin version 2.0.0.4 305 * @see #startReadFromGps 306 * @see #finishReadFromGps 307 */ 308 cancelReadFromGps: function() { 309 this.plugin.CancelReadFromGps(); 310 }, 311 312 /** Start the asynchronous ReadFitnessData operation. <br/> 313 * <br/> 314 * Minimum plugin version 2.1.0.3 for FitnessHistory type<br/> 315 * Minimum plugin version 2.2.0.1 for FitnessWorkouts, FitnessUserProfile, FitnessCourses 316 * 317 * @param deviceNumber {Number} assigned by the plugin. 318 * @param dataTypeName {String} a fitness datatype from the 319 * <a href="http://developer.garmin.com/schemas/device/v2">Garmin Device XML</a> 320 * retrieved with getDeviceDescriptionXml 321 * @see #finishReadFitnessData 322 * @see #cancelReadFitnessData 323 * @see #getDeviceDescriptionXml 324 * @see #getDevicesXml for device number assignment 325 * @see Garmin.DeviceControl#FILE_TYPES 326 */ 327 startReadFitnessData: function(deviceNumber, dataTypeName) { 328 if( !this.checkPluginVersionSupport([2,1,0,3]) ) { 329 throw new Error("Your Communicator Plug-in version (" + this.getPluginVersionString() + ") does not support reading this type of fitness data."); 330 } 331 332 this.plugin.StartReadFitnessData( deviceNumber, dataTypeName ); 333 }, 334 335 /** Poll for completion of the asynchronous ReadFitnessData operation. <br/> 336 * <br/> 337 * If the CompletionState is eMessageWaiting, call MessageBoxXml 338 * to get a description of the message box to be displayed to 339 * the user, and then call RespondToMessageBox with the value of the 340 * selected button to resume operation.<br/> 341 * <br/> 342 * Minimum plugin version 2.1.0.3 for FitnessHistory type <br/> 343 * Minimum plugin version 2.2.0.1 for FitnessWorkouts, FitnessUserProfile, FitnessCourses 344 * 345 * @type Number 346 * @return Completion state - The completion state can be one of the following: <br/> 347 * <br/> 348 * 0 = idle <br/> 349 * 1 = working <br/> 350 * 2 = waiting <br/> 351 * 3 = finished <br/> 352 * @see #startReadFitnessData 353 * @see #cancelReadFitnessData 354 */ 355 finishReadFitnessData: function() { 356 return this.plugin.FinishReadFitnessData(); 357 }, 358 359 /** Cancel the asynchronous ReadFitnessData operation. <br/> 360 * <br/> 361 * Minimum plugin version 2.1.0.3 for FitnessHistory type <br/> 362 * Minimum plugin version 2.2.0.1 for FitnessWorkouts, FitnessUserProfile, FitnessCourses 363 * 364 * @see #startReadFitnessData 365 * @see #finishReadFitnessData 366 */ 367 cancelReadFitnessData: function() { 368 this.plugin.CancelReadFitnessData(); 369 }, 370 371 /** 372 * List all of the FIT files on the device. Starts an asynchronous directory listing operation for the device. 373 * Poll for finished with FinishReadFitDirectory. The result can be retrieved with {@link #getDirectoryXml}. 374 * 375 * Minimum plugin version 2.7.2.0 376 * @see #finishReadFitDirectory 377 */ 378 startReadFitDirectory: function(deviceNumber) { 379 if( !this.getSupportsFitDirectoryRead() ) { 380 throw new Error("Your Communicator Plug-in version (" + this.getPluginVersionString() + ") does not support FIT directory listing data."); 381 } 382 this.plugin.StartReadFITDirectory(deviceNumber); 383 }, 384 385 /** Poll for completion of the asynchronous startReadFitDirectory operation. <br/> 386 * <br/> 387 * Minimum plugin version 2.7.2.0 388 * 389 * @type Number 390 * @return Completion state - The completion state can be one of the following: <br/> 391 * <br/> 392 * 0 = idle <br/> 393 * 1 = working <br/> 394 * 2 = waiting <br/> 395 * 3 = finished <br/> 396 * 397 * @see #startReadFitDirectory 398 * @see #cancelReadFitDirectory 399 * @see #getMessageBoxXml 400 * @see #respondToMessageBox 401 */ 402 finishReadFitDirectory: function() { 403 return this.plugin.FinishReadFITDirectory(); 404 }, 405 406 /** Start the asynchronous ReadFitnessDirectory operation. <br/> 407 * <br/> 408 * Minimum plugin version 2.2.0.2 409 * 410 * @param deviceNumber {Number} assigned by the plugin 411 * @param dataTypeName a Fitness DataType from the GarminDevice.xml retrieved with DeviceDescription 412 * @see #finishReadFitnessDirectory 413 * @see #cancelReadFitnessDirectory 414 * @see #getDevicesXml for device number assignment 415 * @see Garmin.DeviceControl#FILE_TYPES 416 */ 417 startReadFitnessDirectory: function(deviceNumber, dataTypeName) { 418 if( !this.getSupportsFitnessDirectoryRead() ) { 419 throw new Error("Your Communicator Plug-in version (" + this.getPluginVersionString() + ") does not support reading fitness directory data."); 420 } 421 this.plugin.StartReadFitnessDirectory( deviceNumber, dataTypeName); 422 }, 423 424 /** Poll for completion of the asynchronous ReadFitnessDirectory operation. <br/> 425 * <br/> 426 * If the CompletionState is eMessageWaiting, call getMessageBoxXml 427 * to get a description of the message box to be displayed to 428 * the user, and then call respondToMessageBox with the value of the 429 * selected button to resume operation.<br/> 430 * <br/> 431 * Minimum plugin version 2.2.0.2 432 * 433 * @type Number 434 * @return Completion state - The completion state can be one of the following: <br/> 435 * <br/> 436 * 0 = idle <br/> 437 * 1 = working <br/> 438 * 2 = waiting <br/> 439 * 3 = finished <br/> 440 * 441 * @see #startReadFitnessDirectory 442 * @see #cancelReadFitnessDirectory 443 * @see #getMessageBoxXml 444 * @see #respondToMessageBox 445 */ 446 finishReadFitnessDirectory: function() { 447 return this.plugin.FinishReadFitnessDirectory(); 448 }, 449 450 /** Cancel the asynchronous ReadFitnessDirectory operation. <br/> 451 * <br/> 452 * Minimum plugin version 2.2.0.2 453 * 454 * @see #startReadFitnessDirectory 455 * @see #finishReadFitnessDirectory 456 */ 457 cancelReadFitnessDirectory: function() { 458 this.plugin.CancelReadFitnessDirectory(); 459 }, 460 461 /** Cancel the asynchronous ReadFitDirectory operation. <br/> 462 * <br/> 463 * Minimum plugin version 2.7.2.0 464 * 465 * @see #startReadFitDirectory 466 * @see #finishReadFitDirectory 467 */ 468 cancelReadFitDirectory: function() { 469 this.plugin.CancelReadFitDirectory(); 470 }, 471 472 /** Start the asynchronous ReadFitnessDetail operation. <br/> 473 * <br/> 474 * Minimum plugin version 2.2.0.2 475 * 476 * @param deviceNumber assigned by the plugin 477 * @param dataTypeName a Fitness DataType from the GarminDevice.xml retrieved with DeviceDescription 478 * @see #finishReadFitnessDetail 479 * @see #cancelReadFitnessDetail 480 * @see #getDevicesXml for device number assignment 481 * @see Garmin.DeviceControl#FILE_TYPES 482 */ 483 startReadFitnessDetail: function(deviceNumber, dataTypeName, dataId) { 484 if( !this.checkPluginVersionSupport([2,2,0,2]) ) { 485 throw new Error("Your Communicator Plug-in version (" + this.getPluginVersionString() + ") does not support reading fitness detail."); 486 } 487 488 this.plugin.StartReadFitnessDetail(deviceNumber, dataTypeName, dataId); 489 }, 490 491 /** Poll for completion of the asynchronous ReadFitnessDetail operation. <br/> 492 * <br/> 493 * If the CompletionState is eMessageWaiting, call MessageBoxXml 494 * to get a description of the message box to be displayed to 495 * the user, and then call RespondToMessageBox with the value of the 496 * selected button to resume operation.<br/> 497 * <br/> 498 * Minimum plugin version 2.2.0.2 499 * 500 * @type Number 501 * @return Completion state - The completion state can be one of the following: <br/> 502 * <br/> 503 * 0 = idle <br/> 504 * 1 = working <br/> 505 * 2 = waiting <br/> 506 * 3 = finished <br/> 507 * 508 */ 509 finishReadFitnessDetail: function() { 510 return this.plugin.FinishReadFitnessDetail(); 511 }, 512 513 /** Cancel the asynchronous ReadFitnessDirectory operation. <br/> 514 * <br/> 515 * Minimum version 2.2.0.2 516 * 517 * @see #startReadFitnessDetail 518 * @see #finishReadFitnessDetail 519 */ 520 cancelReadFitnessDetail: function() { 521 this.plugin.CancelReadFitnessDetail(); 522 }, 523 524 525 /** Starts an asynchronous file listing operation for a Mass Storage mode device. <br/> 526 * Only files that are output from the device are listed. </br> 527 * The result can be retrieved with {@link #getDirectoryXml}. 528 * Minimum plugin version 2.8.1.0 <br/> 529 * 530 * @param {Number} deviceNumber assigned by the plugin 531 * @param {String} dataTypeName a DataType from GarminDevice.xml retrieved with DeviceDescription 532 * @param {String} fileTypeName a Specification Identifier for a File in dataTypeName from GarminDevice.xml 533 * @param {Boolean} computeMD5 If true, the plug-in will generate an MD5 checksum for each readable file. 534 * 535 * @see #finishReadableFileListing 536 * @see #cancelReadableFileListing 537 * @see #getDevicesXml for device number assignment 538 * @see Garmin.DeviceControl.FILE_TYPES 539 */ 540 startReadableFileListing: function( deviceNumber, dataTypeName, fileTypeName, computeMD5 ) 541 { 542 if( !this.checkPluginVersionSupport([2,8,1,0]) ) 543 { 544 throw new Error("Your Communicator Plug-in version (" + this.getPluginVersionString() + ") does not support listing readable files."); 545 } 546 547 this.plugin.StartReadableFileListing(deviceNumber, dataTypeName, fileTypeName, computeMD5); 548 }, 549 550 /** Cancel the asynchronous ReadableFileListing operation <br/> 551 * Minimum version 2.8.1.0 <br/> 552 * 553 * @see #startReadableFileListing 554 * @see #finishReadableFileListing 555 */ 556 cancelReadableFileListing: function() 557 { 558 this.plugin.CancelReadableFileListing(); 559 }, 560 561 /** Poll for completion of the asynchronous ReadableFileListing operation. <br/> 562 * <br/> 563 * If the CompletionState is eMessageWaiting, call MessageBoxXml 564 * to get a description of the message box to be displayed to 565 * the user, and then call RespondToMessageBox with the value of the 566 * selected button to resume operation.<br/> 567 * <br/> 568 * Minimum version 2.8.1.0 <br/> 569 * 570 * @type Number 571 * @return Completion state - The completion state can be one of the following: <br/> 572 * <br/> 573 * 0 = idle <br/> 574 * 1 = working <br/> 575 * 2 = waiting <br/> 576 * 3 = finished <br/> 577 * 578 */ 579 finishReadableFileListing: function() 580 { 581 return this.plugin.FinishReadableFileListing(); 582 }, 583 584 // Write Methods 585 586 /** Initates writing the gpsXml to the device specified by deviceNumber with a filename set by filename. 587 * The gpsXml is typically in GPX fomat and the filename is only the name without the extension. The 588 * plugin will append the .gpx extension automatically.<br/> 589 * <br/> 590 * Use finishWriteToGps to poll when the write operation/plugin is complete.<br/> 591 * <br/> 592 * Uses the helper functions to set the xml info and the filename. <br/> 593 * <br/> 594 * Minimum plugin version 2.0.0.4<br/> 595 * Minimum plugin version 2.2.0.1 for writes of GPX to SD Card 596 * 597 * @param gpsXml {String} the gps/gpx information that should be transferred to the device. 598 * @param filename {String} the desired filename for the gpsXml that shall end up on the device. 599 * @param deviceNumber {Number} the device number assigned by the plugin. 600 * @see #finishWriteToGps 601 * @see #cancelWriteToGps 602 */ 603 startWriteToGps: function(gpsXml, filename, deviceNumber) { 604 this._setWriteGpsXml(gpsXml); 605 this._setWriteFilename(filename); 606 this.plugin.StartWriteToGps(deviceNumber); 607 }, 608 609 /** Sets the gps xml content that will end up on the device once the transfer is complete. 610 * Use in conjunction with startWriteToGps to initiate the actual write. 611 * 612 * @private 613 * @param gpsXml {String} xml data that is to be written to the device. Must be in GPX format. 614 */ 615 _setWriteGpsXml: function(gpsXml) { 616 this.plugin.GpsXml = gpsXml; 617 }, 618 619 /** This the filename that wil contain the gps xml once the transfer is complete. Use with 620 * setWriteGpsXml to set what the file contents will be. Also, use startWriteToGps to 621 * actually make the write happen. 622 * 623 * @private 624 * @param filename {String} the actual filename that will end up on the device. Should only be the 625 * name and not the extension. The plugin will append the extension portion to the file name--typically .gpx. 626 * @see #setWriteGpsXml, #startWriteToGps, #startWriteFitnessData 627 */ 628 _setWriteFilename: function(filename) { 629 this.plugin.FileName = filename; 630 }, 631 632 /** This is used to indicate the status of the write process. It will return an integer 633 * know as the completion state. The purpose is to show the 634 * user information about what is happening to the plugin while it 635 * is servicing your request. <br/> 636 * <br/> 637 * Minimum plugin version 2.0.0.4<br/> 638 * Minimum plugin version 2.2.0.1 for writes of GPX to SD Card 639 * 640 * @type Number 641 * @return Completion state - The completion state can be one of the following: <br/> 642 * <br/> 643 * 0 = idle <br/> 644 * 1 = working <br/> 645 * 2 = waiting <br/> 646 * 3 = finished <br/> 647 * @see #startWriteToGps 648 * @see #cancelWriteToGps 649 */ 650 finishWriteToGps: function() { 651 //console.debug("Plugin.finishWriteToGps"); 652 return this.plugin.FinishWriteToGps(); 653 }, 654 655 /** Cancels the current write operation to the gps device. <br/> 656 * <br/> 657 * Minimum plugin version 2.0.0.4<br/> 658 * Minimum plugin version 2.2.0.1 for writes of GPX to SD Card 659 * 660 * @see #startWriteToGps 661 * @see #finishWriteToGps 662 */ 663 cancelWriteToGps: function() { 664 this.plugin.CancelWriteToGps(); 665 }, 666 667 /** Start the asynchronous StartWriteFitnessData operation. <br/> 668 * For binary files such as FIT, use {@link #startDownloadData} 669 * <br/> 670 * Minimum plugin version 2.2.0.1 671 * 672 * @param tcdXml {String} XML of TCD data 673 * @param deviceNumber {Number} the device number, assigned by the plugin. 674 * @param filename {String} the filename to write to on the device. 675 * @param dataTypeName {String} a Fitness DataType from the GarminDevice.xml retrieved with DeviceDescription 676 * @see #finishWriteFitnessData 677 * @see #cancelWriteFitnessData 678 * @see #getDevicesXml for device number assignment 679 * @see Garmin.DeviceControl#FILE_TYPES 680 */ 681 startWriteFitnessData: function(tcdXml, deviceNumber, filename, dataTypeName) { 682 if( !this.checkPluginVersionSupport([2,2,0,1]) ) { 683 throw new Error("Your Communicator Plug-in version (" + this.getPluginVersionString() + ") does not support writing fitness data."); 684 } 685 686 this._setWriteTcdXml(tcdXml); 687 this._setWriteFilename(filename); 688 this.plugin.StartWriteFitnessData(deviceNumber, dataTypeName); 689 }, 690 691 /** This is used to indicate the status of the write process for fitness data. It will return an integer 692 * know as the completion state. The purpose is to show the 693 * user information about what is happening to the plugin while it 694 * is servicing your request. <br/> 695 * <br/> 696 * Minimum plugin version 2.2.0.1 697 * 698 * @type Number 699 * @return Completion state - The completion state can be one of the following: <br/> 700 * <br/> 701 * 0 = idle <br/> 702 * 1 = working <br/> 703 * 2 = waiting <br/> 704 * 3 = finished <br/> 705 * @see #startWriteFitnessData 706 * @see #cancelWriteFitnessData 707 */ 708 finishWriteFitnessData: function() { 709 return this.plugin.FinishWriteFitnessData(); 710 }, 711 712 /** Cancel the asynchronous ReadFitnessData operation. <br/> 713 * <br/> 714 * Minimum plugin version 2.2.0.1 715 * 716 * @see #startWriteFitnessData 717 * @see #finishWriteFitnessData 718 */ 719 cancelWriteFitnessData: function() { 720 this.plugin.CancelWriteFitnessData(); 721 }, 722 723 /** Sets the tcd xml content that will end up on the device once the transfer is complete. 724 * Use in conjunction with startWriteFitnessData to initiate the actual write. 725 * 726 * @private 727 * @param tcdXml {String} xml data that is to be written to the device. Must be in TCX format. 728 */ 729 _setWriteTcdXml: function(tcdXml) { 730 this.plugin.TcdXml = tcdXml; 731 }, 732 733 /** 734 * Determine the amount of space available on a Mass Storage Mode Device Volume. 735 * 736 * @param {Number} deviceNumber - the device number assigned by the plugin. 737 * @param {String} relativeFilePath - if a file is being replaced, set to relative path on device, otherwise set to empty string. 738 * @return -1 for non-mass storage mode devices. 739 * @see #getDevicesXml for device number assignment 740 */ 741 bytesAvailable: function(deviceNumber, relativeFilePath) { 742 return this.plugin.BytesAvailable(deviceNumber, relativeFilePath); 743 }, 744 745 /** 746 * Determine if device is file-based. <br/> 747 * File-based devices include Mass Storage Mode Devices such as Nuvi, Oregon, Edge 705, 748 * as well as ANT Proxy Devices.<br/> 749 * 750 * Minimum plugin version 2.8.1.0 <br/> 751 * @param {Number} deviceNumber the device number assigned by the plugin. 752 * @returns {Boolean} true for file based devices, false otherwise 753 * @see #getDevicesXml for device number assignment 754 */ 755 isDeviceFileBased: function(deviceNumber) { 756 var theReturn = true; 757 //do a dummy file listing 758 try { 759 this.startReadableFileListing( deviceNumber, 'FileBasedTest', 'FileBasedTest', false ); 760 while( this.finishReadableFileListing() == 1 ) { 761 //wait until done. Only safe to do because fxn returns quickly because of test name and id! 762 } 763 } catch(e) { 764 theReturn = false; 765 } 766 return theReturn; 767 }, 768 769 /** Responds to a message box on the device. <br/> 770 * <br/> 771 * Minimum plugin version 2.0.0.4 772 * 773 * @param response should be an int which corresponds to a button value from this.plugin.MessageBoxXml 774 */ 775 respondToMessageBox: function(response) { 776 this.plugin.RespondToMessageBox(response); 777 }, 778 779 /** Downloads and writes files asynchronously to the specified device. <br/> 780 * Use {@link #finishDownloadData} to poll when the write operation/plugin is complete.<br/> 781 * <br/> 782 * Minimum plugin version 2.0.0.4 783 * 784 * @param xmlDownloadDescription {String} XML string containing information about the files to be downloaded onto the device.<br/> 785 * This xml must conform to one of two schemas:<br/> 786 * <a href=http://www.garmin.com/xmlschemas/GarminPluginAPIV1.xsd>GarminPluginAPIV1</a> <br/> 787 * <a href=http://www.garmin.com/xmlschemas/DeviceDownloadV1.xsd>DeviceDownloadV1</a> <strong>Recommended</strong> <br/> 788 * @param deviceNumber {Number} the device number assigned by the plugin. 789 * @see #finishDownloadData 790 * @see #cancelDownloadData 791 * @see #Garmin.GpiUtil 792 */ 793 startDownloadData: function(xmlDownloadDescription, deviceNumber) { 794 this.plugin.StartDownloadData(xmlDownloadDescription, deviceNumber); 795 }, 796 797 /** This is used to indicate the status of the download process. It will return an integer 798 * know as the completion state. The purpose is to show the 799 * user information about what is happening to the plugin while it 800 * is servicing your request.<br/> 801 * <br/> 802 * Minimum plugin version 2.0.0.4 803 * 804 * @type Number 805 * @return Completion state - The completion state can be one of the following: <br/> 806 * <br/> 807 * 0 = idle <br/> 808 * 1 = working <br/> 809 * 2 = waiting <br/> 810 * 3 = finished <br/> 811 * @see #startDownloadData 812 * @see #cancelDownloadData 813 */ 814 finishDownloadData: function() { 815 //console.debug("Plugin.finishDownloadData"); 816 return this.plugin.FinishDownloadData(); 817 }, 818 819 /** Cancel the asynchronous Download Data operation. <br/> 820 * <br/> 821 * Minimum plugin version 2.0.0.4 822 * 823 * @see #startDownloadData 824 * @see #finishDownloadData 825 */ 826 cancelDownloadData: function() { 827 this.plugin.CancelDownloadData(); 828 }, 829 830 /** Indicates success of StartDownloadData operation. <br/> 831 * <br/> 832 * Minimum plugin version 2.0.0.4 833 * 834 * @type Boolean 835 * @return True if the last StartDownloadData operation was successful 836 */ 837 downloadDataSucceeded: function() { 838 return this.plugin.DownloadDataSucceeded; 839 }, 840 841 /** Download and install a list of unit software updates. Start the asynchronous 842 * StartUnitSoftwareUpdate operation. 843 * 844 * Check for completion with the FinishUnitSoftwareUpdate() method. After 845 * completion check the DownloadDataSucceeded property to make sure that all of the downloads 846 * were successfully placed on the device. 847 * 848 * See the Schema UnitSoftwareUpdatev3.xsd for the format of the UpdateResponsesXml description 849 * 850 * @see Garmin.DevicePlugin.finishUnitSoftwareUpdate 851 * @see Garmin.DevicePlugin.cancelUnitSoftwareUpdate 852 * @see Garmin.DevicePlugin.downloadDataSucceeded 853 * @version plugin v2.6.2.0 854 */ 855 startUnitSoftwareUpdate: function(updateResponsesXml, deviceNumber) { 856 this.plugin.StartUnitSoftwareUpdate(updateResponsesXml, deviceNumber); 857 }, 858 859 /** Poll for completion of the asynchronous Unit Software Update operation. It will return an integer 860 * know as the completion state. The purpose is to show the 861 * user information about what is happening to the plugin while it 862 * is servicing your request.<br/> 863 * @type Number 864 * @version plugin v2.6.2.0 865 * @return Completion state - The completion state can be one of the following: <br/> 866 * <br/> 867 * 0 = idle <br/> 868 * 1 = working <br/> 869 * 2 = waiting <br/> 870 * 3 = finished <br/> 871 * @see Garmin.DevicePlugin.startUnitSoftwareUpdate 872 * @see Garmin.DevicePlugin.cancelUnitSoftwareUpdate 873 */ 874 finishUnitSoftwareUpdate: function() { 875 return this.plugin.FinishUnitSoftwareUpdate(); 876 }, 877 878 /** Cancel the asynchrous Download Data operation 879 * @version plugin v2.6.2.0 880 */ 881 cancelUnitSoftwareUpdate: function() { 882 this.plugin.CancelUnitSoftwareUpdate(); 883 }, 884 885 /** Get the UnitSoftwareUpdateRequests for a given device. 886 * This request retrieves the main system software (system region only.) 887 * @param deviceNumber {Number} the device number to retrieve unit software information for. 888 * @return {String} XML string of the document format in the namespace below, or 889 * the most current version of that xms namespace 890 * http://www.garmin.com/xmlschemas/UnitSoftwareUpdate/v3 891 * @version plugin v2.6.2.0 892 * @see Garmin.DevicePlugin.getAdditionalSoftwareUpdateRequests 893 */ 894 // getUnitSoftwareUpdateRequests: function(deviceNumber) { 895 // return this.plugin.UnitSoftwareUpdateRequests(deviceNumber); 896 // }, 897 898 /** Get the AdditionalSoftwareUpdateRequests for a given device. 899 * This request retrieves the additional system software (all software except for system region.) 900 * @param deviceNumber {Number} the device number to retrieve unit software information for. 901 * @return {String} XML string of the document format in the namespace below, or 902 * the most current version of that xms namespace 903 * http://www.garmin.com/xmlschemas/UnitSoftwareUpdate/v3 904 * @version plugin v2.6.2.0 905 * @see Garmin.DevicePlugin.getUnitSoftwareUpdateRequests 906 */ 907 // getAdditionalSoftwareUpdateRequests: function(deviceNumber) { 908 // return this.plugin.AdditionalSoftwareUpdateRequests(deviceNumber); 909 // }, 910 911 /** Indicates success of WriteToGps operation. <br/> 912 * <br/> 913 * Minimum plugin version 2.0.0.4 914 * 915 * @type Boolean 916 * @return True if the last ReadFromGps or WriteToGps operation was successful 917 */ 918 gpsTransferSucceeded: function() { 919 return this.plugin.GpsTransferSucceeded; 920 }, 921 922 /** Indicates success of ReadFitnessData or WriteFitnessData operation. <br/> 923 * <br/> 924 * Minimum plugin version 2.1.0.3 925 * 926 * @type Boolean 927 * @return True if the last ReadFitnessData or WriteFitnessData operation succeeded 928 */ 929 fitnessTransferSucceeded: function() { 930 return this.plugin.FitnessTransferSucceeded; 931 }, 932 933 /** Return the specified file as a UU-Encoded string 934 * <br/> 935 * Minimum version 2.6.3.1 936 * 937 * If the file is known to be compressed, compressed should be 938 * set to false. Otherwise, set compressed to true to retrieve a 939 * gzipped and uuencoded file. 940 * 941 * @param relativeFilePath {String} path relative to the Garmin folder on the device 942 */ 943 getBinaryFile: function(deviceNumber, relativeFilePath, compressed) { 944 return this.plugin.GetBinaryFile(deviceNumber, relativeFilePath, compressed); 945 }, 946 947 /** This is the GpsXml information from the device. Typically called after a read operation. 948 * 949 * @see #finishReadFromGps 950 */ 951 getGpsXml: function(){ 952 return this.plugin.GpsXml; 953 }, 954 955 /** This is the fitness data Xml information from the device. Typically called after a ReadFitnessData operation. <br/> 956 * <br/> 957 * Schemas for the TrainingCenterDatabase format are available at 958 * <a href="http://developer.garmin.com/schemas/tcx/v2/">http://developer.garmin.com/schemas/tcx/v2/</a><br/> 959 * <br/> 960 * Minimum plugin version 2.1.0.3 961 * 962 * @see #finishReadFitnessData 963 * @see #finishReadFitnessDirectory 964 * @see #finishReadFitnessDetail 965 */ 966 getTcdXml: function(){ 967 return this.plugin.TcdXml; 968 }, 969 970 /** Returns last read fitness xml data in compressed format. The xml is compressed as gzp and base64 expanded. <br/> 971 * <br/> 972 * Minimum plugin version 2.2.0.2 973 * 974 * @return The read xml data in compressed gzp and base64 expanded format. 975 * @see #finishReadFitnessData 976 * @see #finishReadFitnessDirectory 977 * @see #finishReadFitnessDetail 978 */ 979 getTcdXmlz: function() { 980 return this.plugin.TcdXmlz; 981 }, 982 983 /** Returns last read directory xml data.<br/> 984 * <br/> 985 * 986 * @return The directory xml data 987 * @see #finishReadFitDirectory 988 */ 989 getDirectoryXml: function() { 990 return this.plugin.DirectoryListingXml; 991 }, 992 993 /** Returns the xml describing the message when the plug-in is waiting for input from the user. 994 * @type String 995 * @return The xml describing the message when the plug-in is waiting for input from the user. 996 */ 997 getMessageBoxXml: function(){ 998 return this.plugin.MessageBoxXml; 999 }, 1000 1001 /** Get the status/progress of the current state or transfer. 1002 * @type String 1003 * @return The xml describing the current progress state of the plug-in. 1004 */ 1005 getProgressXml: function() { 1006 return this.plugin.ProgressXml; 1007 }, 1008 1009 /** Returns metadata information about the plugin version. 1010 * @type String 1011 * @return The xml describing the user's version of the plug-in. 1012 */ 1013 getVersionXml: function() { 1014 return this.plugin.VersionXml; 1015 }, 1016 1017 /** Gets a string of the version number for the plugin the user has currently installed. 1018 * @type String 1019 * @return A string of the format "versionMajor.versionMinor.buildMajor.buildMinor", ex: "2.0.0.4" 1020 */ 1021 getPluginVersionString: function() { 1022 var versionArray = this.getPluginVersion(); 1023 1024 var versionString = versionArray[0] + "." + versionArray[1] + "." + versionArray[2] + "." + versionArray[3]; 1025 return versionString; 1026 }, 1027 1028 /** Gets the version number for the plugin the user has currently installed. 1029 * @type Array 1030 * @return An array of the format: [versionMajor, versionMinor, buildMajor, buildMinor]. 1031 */ 1032 getPluginVersion: function() { 1033 var versionMajor = parseInt(this._getElementValue(this.getVersionXml(), "VersionMajor")); 1034 var versionMinor = parseInt(this._getElementValue(this.getVersionXml(), "VersionMinor")); 1035 var buildMajor = parseInt(this._getElementValue(this.getVersionXml(), "BuildMajor")); 1036 var buildMinor = parseInt(this._getElementValue(this.getVersionXml(), "BuildMinor")); 1037 1038 var versionArray = [versionMajor, versionMinor, buildMajor, buildMinor]; 1039 return versionArray; 1040 }, 1041 1042 /** Sets the required plugin version number for the application. 1043 * @param reqVersionArray {Array} The required version to set to. In the format [versionMajor, versionMinor, buildMajor, buildMinor] 1044 * i.e. [2,2,0,1] 1045 */ 1046 setPluginRequiredVersion: function(reqVersionArray) { 1047 Garmin.DevicePlugin.REQUIRED_VERSION.versionMajor = reqVersionArray[0]; 1048 Garmin.DevicePlugin.REQUIRED_VERSION.versionMinor = reqVersionArray[1]; 1049 Garmin.DevicePlugin.REQUIRED_VERSION.buildMajor = reqVersionArray[2]; 1050 Garmin.DevicePlugin.REQUIRED_VERSION.buildMinor = reqVersionArray[3]; 1051 }, 1052 1053 /** Sets the latest plugin version number. This represents the latest version available for download at Garmin. 1054 * We will attempt to keep the default value of this up to date with each API release, but this is not guaranteed, 1055 * so set this to be safe or if you don't want to upgrade to the latest API. 1056 * 1057 * @param reqVersionArray {Array} The latest version to set to. In the format [versionMajor, versionMinor, buildMajor, buildMinor] 1058 * i.e. [2,2,0,1] 1059 */ 1060 setPluginLatestVersion: function(reqVersionArray) { 1061 Garmin.DevicePlugin.LATEST_VERSION.versionMajor = reqVersionArray[0]; 1062 Garmin.DevicePlugin.LATEST_VERSION.versionMinor = reqVersionArray[1]; 1063 Garmin.DevicePlugin.LATEST_VERSION.buildMajor = reqVersionArray[2]; 1064 Garmin.DevicePlugin.LATEST_VERSION.buildMinor = reqVersionArray[3]; 1065 }, 1066 1067 /** Used to check if the user's installed plugin version meets the required version for feature support purposes. 1068 * 1069 * @param {Array} reqVersionArray An array representing the required version, in the format: [versionMajor, versionMinor, buildMajor, buildMinor]. 1070 * @return {boolean} true if the passed in required version is met by the user's plugin version (user's version is equal to or greater), false otherwise. 1071 * @see setPluginRequiredVersion 1072 */ 1073 checkPluginVersionSupport: function(reqVersionArray) { 1074 1075 var pVersion = this._versionToNumber(this.getPluginVersion()); 1076 var rVersion = this._versionToNumber(reqVersionArray); 1077 return (pVersion >= rVersion); 1078 }, 1079 1080 /** 1081 * @private 1082 */ 1083 _versionToNumber: function(versionArray) { 1084 if (versionArray[1] > 99 || versionArray[2] > 99 || versionArray[3] > 99) 1085 throw new Error("version segment is greater than 99: "+versionArray); 1086 return 1000000*versionArray[0] + 10000*versionArray[1] + 100*versionArray[2] + versionArray[3]; 1087 }, 1088 1089 /** Determines if the Garmin plugin is at least the required version for the application. 1090 * @type Boolean 1091 * @see setPluginRequiredVersion 1092 */ 1093 isPluginOutOfDate: function() { 1094 var pVersion = this._versionToNumber(this.getPluginVersion()); 1095 var rVersion = this._versionToNumber(Garmin.DevicePlugin.REQUIRED_VERSION.toArray()); 1096 return (pVersion < rVersion); 1097 }, 1098 1099 /** Checks if plugin is the most recent version released, for those that want the latest and greatest. 1100 */ 1101 isUpdateAvailable: function() { 1102 var pVersion = this._versionToNumber(this.getPluginVersion()); 1103 var cVersion = this._versionToNumber(Garmin.DevicePlugin.LATEST_VERSION.toArray()); 1104 return (pVersion < cVersion); 1105 }, 1106 1107 /** Pulls value from xml given an element name or null if no tag exists with that name. 1108 * @private 1109 */ 1110 _getElementValue: function(xml, tagName) { 1111 var start = xml.indexOf("<"+tagName+">"); 1112 if (start == -1) 1113 return null; 1114 start += tagName.length+2; 1115 var end = xml.indexOf("</"+tagName+">"); 1116 var result = xml.substring(start, end); 1117 return result; 1118 } 1119 1120 }; 1121 1122 /** Latest version (not required) of the Garmin Communicator Plugin, and a complementary toString function to print it out with 1123 */ 1124 Garmin.DevicePlugin.LATEST_VERSION = { 1125 versionMajor: 3, 1126 versionMinor: 0, 1127 buildMajor: 1, 1128 buildMinor: 0, 1129 1130 toString: function() { 1131 return this.versionMajor + "." + this.versionMinor + "." + this.buildMajor + "." + this.buildMinor; 1132 }, 1133 1134 toArray: function() { 1135 return [this.versionMajor, this.versionMinor, this.buildMajor, this.buildMinor]; 1136 } 1137 }; 1138 1139 1140 /** Latest required version of the Garmin Communicator Plugin, and a complementary toString function to print it out with. 1141 */ 1142 Garmin.DevicePlugin.REQUIRED_VERSION = { 1143 versionMajor: 3, 1144 versionMinor: 0, 1145 buildMajor: 0, 1146 buildMinor: 0, 1147 1148 toString: function() { 1149 return this.versionMajor + "." + this.versionMinor + "." + this.buildMajor + "." + this.buildMinor; 1150 }, 1151 1152 toArray: function() { 1153 return [this.versionMajor, this.versionMinor, this.buildMajor, this.buildMinor]; 1154 } 1155 };