⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdevice.cpp

📁 QLandkarte - use your Garmin GPS with Linux Requirements: * > Qt 4.2.x (Qt 4.1.x will not wo
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************************************    Copyright (C) 2007 Oliver Eichler oliver.eichler@gmx.de    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA  Garmin and MapSource are registered trademarks or trademarks of Garmin Ltd.  or one of its subsidiaries.**********************************************************************************************/#include "CDevice.h"#include <Garmin.h>#include <errno.h>#include <iostream>#include <sstream>using namespace GPSMap60CSx;using namespace Garmin;using namespace std;namespace GPSMap60CSx{    static const char _clrtbl[1024]={    0,0,0,0,32,0,0,0,65,0,0,0,106,0,0,0,-117,0,0,0,    -76,0,0,0,-43,0,0,0,-1,0,0,0,0,48,0,0,32,48,0,0,    65,48,0,0,106,48,0,0,-117,48,0,0,-76,48,0,0,-43,48,0,0,    -1,48,0,0,0,101,0,0,32,101,0,0,65,101,0,0,106,101,0,0,    -117,101,0,0,-76,101,0,0,-43,101,0,0,-1,101,0,0,0,-107,0,0,    32,-107,0,0,65,-107,0,0,106,-107,0,0,-117,-107,0,0,-76,-107,0,0,    -43,-107,0,0,-1,-107,0,0,0,-54,0,0,32,-54,0,0,65,-54,0,0,    106,-54,0,0,-117,-54,0,0,-76,-54,0,0,-43,-54,0,0,-1,-54,0,0,    0,-1,0,0,32,-1,0,0,65,-1,0,0,106,-1,0,0,-117,-1,0,0,    -76,-1,0,0,-43,-1,0,0,-1,-1,0,0,0,0,57,0,32,0,57,0,    65,0,57,0,106,0,57,0,-117,0,57,0,-76,0,57,0,-43,0,57,0,    -1,0,57,0,0,48,57,0,32,48,57,0,65,48,57,0,106,48,57,0,    -117,48,57,0,-76,48,57,0,-43,48,57,0,-1,48,57,0,0,101,57,0,    32,101,57,0,65,101,57,0,106,101,57,0,-117,101,57,0,-76,101,57,0,    -43,101,57,0,-1,101,57,0,0,-107,57,0,32,-107,57,0,65,-107,57,0,    106,-107,57,0,-117,-107,57,0,-76,-107,57,0,-43,-107,57,0,-1,-107,57,0,    0,-54,57,0,32,-54,57,0,65,-54,57,0,106,-54,57,0,-117,-54,57,0,    -76,-54,57,0,-43,-54,57,0,-1,-54,57,0,0,-1,57,0,32,-1,57,0,    65,-1,57,0,106,-1,57,0,-117,-1,57,0,-76,-1,57,0,-43,-1,57,0,    -1,-1,57,0,0,0,123,0,32,0,123,0,65,0,123,0,106,0,123,0,    -117,0,123,0,-76,0,123,0,-43,0,123,0,-1,0,123,0,0,48,123,0,    32,48,123,0,65,48,123,0,106,48,123,0,-117,48,123,0,-76,48,123,0,    -43,48,123,0,-1,48,123,0,0,101,123,0,32,101,123,0,65,101,123,0,    106,101,123,0,-117,101,123,0,-76,101,123,0,-43,101,123,0,-1,101,123,0,    0,-107,123,0,32,-107,123,0,65,-107,123,0,106,-107,123,0,-117,-107,123,0,    -76,-107,123,0,-43,-107,123,0,-1,-107,123,0,0,-54,123,0,32,-54,123,0,    65,-54,123,0,106,-54,123,0,-117,-54,123,0,-76,-54,123,0,-43,-54,123,0,    -1,-54,123,0,0,-1,123,0,32,-1,123,0,65,-1,123,0,106,-1,123,0,    -117,-1,123,0,-76,-1,123,0,-43,-1,123,0,-1,-1,123,0,0,0,-67,0,    32,0,-67,0,65,0,-67,0,106,0,-67,0,-117,0,-67,0,-76,0,-67,0,    -43,0,-67,0,-1,0,-67,0,0,48,-67,0,32,48,-67,0,65,48,-67,0,    106,48,-67,0,-117,48,-67,0,-76,48,-67,0,-43,48,-67,0,-1,48,-67,0,    0,101,-67,0,32,101,-67,0,65,101,-67,0,106,101,-67,0,-117,101,-67,0,    -76,101,-67,0,-43,101,-67,0,-1,101,-67,0,0,-107,-67,0,32,-107,-67,0,    65,-107,-67,0,106,-107,-67,0,-117,-107,-67,0,-76,-107,-67,0,-43,-107,-67,0,    -1,-107,-67,0,0,-54,-67,0,32,-54,-67,0,65,-54,-67,0,106,-54,-67,0,    -117,-54,-67,0,-76,-54,-67,0,-43,-54,-67,0,-1,-54,-67,0,0,-1,-67,0,    32,-1,-67,0,65,-1,-67,0,106,-1,-67,0,-117,-1,-67,0,-76,-1,-67,0,    -43,-1,-67,0,-1,-1,-67,0,0,0,-1,0,32,0,-1,0,65,0,-1,0,    106,0,-1,0,-117,0,-1,0,-76,0,-1,0,-43,0,-1,0,-1,0,-1,0,    0,48,-1,0,32,48,-1,0,65,48,-1,0,106,48,-1,0,-117,48,-1,0,    -76,48,-1,0,-43,48,-1,0,-1,48,-1,0,0,101,-1,0,32,101,-1,0,    65,101,-1,0,106,101,-1,0,-117,101,-1,0,-76,101,-1,0,-43,101,-1,0,    -1,101,-1,0,0,-107,-1,0,32,-107,-1,0,65,-107,-1,0,106,-107,-1,0,    -117,-107,-1,0,-76,-107,-1,0,-43,-107,-1,0,-1,-107,-1,0,0,-54,-1,0,    32,-54,-1,0,65,-54,-1,0,106,-54,-1,0,-117,-54,-1,0,-76,-54,-1,0,    -43,-54,-1,0,-1,-54,-1,0,0,-1,-1,0,32,-1,-1,0,65,-1,-1,0,    106,-1,-1,0,-117,-1,-1,0,-76,-1,-1,0,-43,-1,-1,0,-1,-1,-1,0,    -1,-1,-1,0,-26,-26,-26,0,-43,-43,-43,0,-59,-59,-59,0,-76,-76,-76,0,    -92,-92,-92,0,-108,-108,-108,0,-125,-125,-125,0,115,115,115,0,98,98,98,0,    82,82,82,0,65,65,65,0,49,49,49,0,32,32,32,0,16,16,16,0,    0,0,0,0};    class CMutexLocker    {        public:            CMutexLocker(pthread_mutex_t& mutex)                : mutex(mutex)            {                pthread_mutex_lock(&mutex);            }            ~CMutexLocker()            {                pthread_mutex_unlock(&mutex);            }        private:            pthread_mutex_t& mutex;    };    void * rtThread(void *ptr)    {        cout << "start thread" << endl;        Packet_t command;        Packet_t response;        CDevice * dev = (CDevice*)ptr;        CMutexLocker lock(dev->mutex);        try{            pthread_mutex_lock(&dev->dataMutex);            dev->_acquire();            command.type = GUSB_APPLICATION_LAYER;            command.id   = Pid_Command_Data;            command.size = 2;            *(uint16_t*)command.payload = Cmnd_Start_Pvt_Data;            dev->usb->write(command);            while(dev->doRealtimeThread){                pthread_mutex_unlock(&dev->dataMutex);                if(dev->usb->read(response)){                    if(response.id == Pid_Pvt_Data){                        D800_Pvt_Data_t * srcPvt = (D800_Pvt_Data_t*)response.payload;                        pthread_mutex_lock(&dev->dataMutex);                        dev->PositionVelocityTime << *srcPvt;                        pthread_mutex_unlock(&dev->dataMutex);                    }                }                pthread_mutex_lock(&dev->dataMutex);            }            command.type = GUSB_APPLICATION_LAYER;            command.id   = Pid_Command_Data;            command.size = 2;            *(uint16_t*)command.payload = Cmnd_Stop_Pvt_Data;            dev->usb->write(command);            dev->_release();            pthread_mutex_unlock(&dev->dataMutex);        }        catch(exce_t& e){            pthread_mutex_trylock(&dev->dataMutex);            dev->lasterror = "Realtime thread failed. " + e.msg;            dev->doRealtimeThread = false;            pthread_mutex_unlock(&dev->dataMutex);        }        cout << "stop thread" << endl;        return 0;    }}CDevice::CDevice()    : devid(0)    , usb(0)    , doRealtimeThread(false)    , pScreen(0){    pthread_mutex_init(&dataMutex, NULL);}CDevice::~CDevice(){    if(pScreen) delete [] pScreen;}const string& CDevice::getCopyright(){    copyright = "<h1>QLandkarte Device Driver for Garmin " + devname + "</h1>"                "<h2>Driver I/F Ver. " INTERFACE_VERSION "</h2>"                "<p>&#169; 2007 by Oliver Eichler (oliver.eichler@gmx.de)</p>"                "<p>&#169; Venture HC Screenshot support by Torsten Reuschel (me@fuesika.de)</p>"                "<p>This driver is distributed in the hope that it will be useful, "                "but WITHOUT ANY WARRANTY; without even the implied warranty of "                "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "                "GNU General Public License for more details. </p>";    return copyright;}void CDevice::_acquire(){    usb = new CUSB();    usb->open();    if(devid == 0x01a5){        Packet_t command;        command.type = GUSB_PROTOCOL_LAYER;        command.id   = GUSB_SESSION_START;        command.size = 0;        *(uint16_t*)command.payload = 0x0000;        usb->write(command);        usb->write(command);    }    usb->syncup();    if(strncmp(usb->getProductString().c_str(), devname.c_str(), devname.size()) != 0){        string msg = "No " + devname + " unit detected. Please retry to select other device driver.";        throw exce_t(errSync,msg);    }    if(devid){        if(usb->getProductId() != devid){            string msg = "No " + devname + " unit detected. Please retry to select other device driver.";            throw exce_t(errSync,msg);        }    }    else{        if(usb->getProductId() != 0x0124 && usb->getProductId() != 0x0272){            string msg = "No " + devname + " unit detected. Please retry to select other device driver.";            throw exce_t(errSync,msg);        }    }}void CDevice::_uploadMap(const uint8_t * mapdata, uint32_t size, const char * key, void (*callback)(uint32_t,uint32_t,void*), void* data){    if(usb == 0) return;    Packet_t command;    Packet_t response;    // ???    command.type = GUSB_APPLICATION_LAYER;    command.id   = 0x1C;    command.size = 2;    *(uint16_t*)command.payload = 0x0000;    usb->write(command);    // read SD Ram capacity    command.type = GUSB_APPLICATION_LAYER;    command.id   = Pid_Command_Data;    command.size = 2;    *(uint16_t*)command.payload = Cmnd_Transfer_Mem;    usb->write(command);    bool started = false;    while(usb->read(response)){        if(response.id == Pid_Capacity_Data){            cout << "free memory: " << dec << (((uint32_t*)response.payload)[1] / (1024*1024)) << " MB" << endl;            uint32_t memory = ((uint32_t*)response.payload)[1];            if(memory < size){                stringstream msg;                msg << "Failed to send map: Unit has not enought memory (available/needed): " << memory << "/" << size << " bytes";                throw exce_t(errRuntime,msg.str());            }            started = true;        }        if(response.type == 0 && response.id == 0 && started ){            break;                // no bytes returned, so I guess we are done        }    }    // send unlock key if present    if(key){        command.type = GUSB_APPLICATION_LAYER;        command.id   = Pid_Tx_Unlock_Key;        command.size = strlen(key) + 1;        memcpy(command.payload,key,command.size);        usb->write(command);        while(usb->read(response)){            if(response.id == Pid_Ack_Unlock_key){                //TODO read data            }        }    }    // switch to map transfer mode erase old map(?)    command.type = GUSB_APPLICATION_LAYER;    command.id   = 75;    command.size = 2;    *(uint16_t*)command.payload = 0x000A;    usb->write(command);    started = false;    while(usb->read(response)){        if(response.id == 74){            //TODO read data            started = true;        }        if(response.type == 0 && response.id == 0 && started ){            break;                // no bytes returned, so I guess we are done        }    }    uint32_t total  = size;    uint32_t offset = 0, chunkSize;    command.type = GUSB_APPLICATION_LAYER;    command.id   = 36;    // transfer file by chunks of 0x1000 - 0x0000C - sizeof(offset) = 0x0FF0 bytes    while(size){        chunkSize       = (size < (GUSB_PAYLOAD_SIZE - sizeof(offset))) ? size : (GUSB_PAYLOAD_SIZE - sizeof(offset));        command.size    = chunkSize + sizeof(offset);        *(uint32_t*)command.payload = offset;        memcpy(command.payload + sizeof(offset),mapdata,chunkSize);        size    -= chunkSize;        mapdata += chunkSize;        offset  += chunkSize;        usb->write(command);        if(callback) callback(total - size, total, data);    }    // terminate map transfer mode (?)    command.type = GUSB_APPLICATION_LAYER;    command.id   = 45;    command.size = 2;    *(uint16_t*)command.payload = 0x000A;    usb->write(command);}void CDevice::_queryMap(std::list<Map_t>& maps){    maps.clear();    if(usb == 0) return;    Packet_t command;    Packet_t response;    // ???    command.type = GUSB_APPLICATION_LAYER;    command.id   = 0x1C;    command.size = 2;    *(uint16_t*)command.payload = 0x0000;    usb->write(command);    // Request map overview table    command.type = GUSB_APPLICATION_LAYER;    command.id   = 0x59;    command.size = 19;    Map_Request_t * req = (Map_Request_t*)command.payload;    req->dummy1 = 0;    req->dummy2 = 10;    strcpy(req->section,"MAPSOURC.MPS");    usb->write(command);    uint32_t size   = 1024;    uint32_t fill   = 0;    char * pData    = (char*)calloc(1,size);//    usb->setBulkRead( false);    bool started = false;    while(usb->read(response)){        // acknowledge request (???)        if(response.id == 0x5B){            //TODO: read data        }        // chunk of MAPSOURC.MPS section        // Each chunk is prepended by a chunk counter of type uint8_t.        // This has to be skipped. That's why the peculiar math.        if(response.id == 0x5A){            // realloc memory if chunk does not fit            if((fill +  response.size - 1) > size){                size += size;                pData = (char*)realloc(pData,size);            }            memcpy(&pData[fill], response.payload + 1, response.size - 1);            fill += response.size - 1;            started = true;        }        if(response.type == 0 && response.id == 0 && started ){//        	  usb->setBulkRead( true);            break;                // no bytes returned, so I guess we are done        }    }    Map_Info_t * pInfo = (Map_Info_t*)pData;    while(pInfo->tok == 0x4C){        Map_t m;        char * pStr = pInfo->name1;        m.mapName = pStr;        pStr += strlen(pStr) + 1;        m.tileName = pStr;        maps.push_back(m);        pInfo =  (Map_Info_t*)(((char*)pInfo) + pInfo->size + sizeof(pInfo->tok) + sizeof(pInfo->size));    }    free(pData);}void CDevice::_downloadWaypoints(list<Garmin::Wpt_t>& waypoints){    waypoints.clear();    if(usb == 0) return;    Packet_t command;    Packet_t response;    // ???    command.type = GUSB_APPLICATION_LAYER;    command.id   = 0x1C;    command.size = 2;    *(uint16_t*)command.payload = 0x0000;    usb->write(command);    // request waypoints    command.type = GUSB_APPLICATION_LAYER;    command.id   = Pid_Command_Data;    command.size = 2;    *(uint16_t*)command.payload = Cmnd_Transfer_Wpt;    usb->write(command);    while(1){        if(!usb->read(response)) continue;        if(response.id == Pid_Records){#ifdef DBG_SHOW_WAYPOINT            cout << "number of waypoints:" << *(int16_t*)response.payload << endl;#endif        }        if(response.id == Pid_Wpt_Data){            D110_Wpt_t * srcWpt = (D110_Wpt_t*)response.payload;            waypoints.push_back(Wpt_t());            Wpt_t& tarWpt = waypoints.back();            tarWpt << *srcWpt;        }        if(response.id == Pid_Xfer_Cmplt){            break;        }    }    // request proximity waypoints    command.type = GUSB_APPLICATION_LAYER;    command.id   = Pid_Command_Data;    command.size = 2;    *(uint16_t*)command.payload = Cmnd_Transfer_Prx;    usb->write(command);    while(1){        if(!usb->read(response)) continue;        if(response.id == Pid_Records){            //TODO read data#ifdef DBG_SHOW_WAYPOINT            cout << "number of proximity waypoints:" << *(int16_t*)response.payload << endl;#endif        }        if(response.id == Pid_Prx_Wpt_Data){            D110_Wpt_t * srcWpt = (D110_Wpt_t*)response.payload;            waypoints.push_back(Wpt_t());            Wpt_t& tarWpt = waypoints.back();            tarWpt << *srcWpt;        }        if(response.id == Pid_Xfer_Cmplt){            break;        }    }#ifdef DBG_SHOW_WAYPOINT    list<Wpt_t>::const_iterator wpt = waypoints.begin();    while(wpt != waypoints.end()){        cout << "-------------------------" << endl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -