Home | History | Annotate | Download | only in ClientLib
      1 /** @addtogroup MCD_IMPL_LIB
      2  * @{
      3  * @file
      4  *
      5  * Client library device management.
      6  *
      7  * Device and Trustlet Session management Funtions.
      8  *
      9  * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  * 3. The name of the author may not be used to endorse or promote
     20  *    products derived from this software without specific prior
     21  *    written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     24  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     27  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     29  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34  */
     35 #include <stdint.h>
     36 #include <vector>
     37 
     38 #include "mc_linux.h"
     39 #include "Device.h"
     40 
     41 #include "log.h"
     42 #include <assert.h>
     43 
     44 
     45 //------------------------------------------------------------------------------
     46 Device::Device(uint32_t deviceId, Connection *connection)
     47 {
     48     this->deviceId = deviceId;
     49     this->connection = connection;
     50 
     51     pMcKMod = new CMcKMod();
     52 }
     53 
     54 
     55 //------------------------------------------------------------------------------
     56 Device::~Device(void)
     57 {
     58     /* Delete all session objects. Usually this should not be needed as closeDevice()
     59      * requires that all sessions have been closed before.
     60      */
     61     sessionIterator_t  sessionIterator = sessionList.begin();
     62     while (sessionIterator != sessionList.end()) {
     63         delete (*sessionIterator);
     64         sessionIterator = sessionList.erase(sessionIterator);
     65     }
     66 
     67     // Free all allocated WSM descriptors
     68     wsmIterator_t  wsmIterator = wsmL2List.begin();
     69     while (wsmIterator != wsmL2List.end()) {
     70         CWsm_ptr pWsm = *wsmIterator;
     71 
     72         // ignore return code
     73         pMcKMod->free(pWsm->handle, pWsm->virtAddr, pWsm->len);
     74 
     75         delete (*wsmIterator);
     76         wsmIterator = wsmL2List.erase(wsmIterator);
     77     }
     78     delete connection;
     79     delete pMcKMod;
     80 }
     81 
     82 
     83 //------------------------------------------------------------------------------
     84 bool Device::open(const char *deviceName)
     85 {
     86     return pMcKMod->open(deviceName);
     87 }
     88 
     89 
     90 //------------------------------------------------------------------------------
     91 void Device::close(void)
     92 {
     93     pMcKMod->close();
     94 }
     95 
     96 
     97 //------------------------------------------------------------------------------
     98 bool Device::hasSessions(void)
     99 {
    100     return sessionList.size() > 0;
    101 }
    102 
    103 
    104 //------------------------------------------------------------------------------
    105 void Device::createNewSession(uint32_t sessionId, Connection  *connection)
    106 {
    107     Session *session = new Session(sessionId, pMcKMod, connection);
    108     sessionList.push_back(session);
    109 }
    110 
    111 
    112 //------------------------------------------------------------------------------
    113 bool Device::removeSession(uint32_t sessionId)
    114 {
    115     bool ret = false;
    116 
    117     sessionIterator_t interator = sessionList.begin();
    118     while (interator != sessionList.end()) {
    119         if ((*interator)->sessionId == sessionId) {
    120             delete (*interator);
    121             interator = sessionList.erase(interator);
    122             ret = true;
    123             break;
    124         } else {
    125             interator++;
    126         }
    127     }
    128     return ret;
    129 }
    130 
    131 
    132 //------------------------------------------------------------------------------
    133 Session *Device::resolveSessionId(uint32_t sessionId)
    134 {
    135     Session  *ret = NULL;
    136 
    137     // Get Session for sessionId
    138     for ( sessionIterator_t interator = sessionList.begin();
    139             interator != sessionList.end();
    140             ++interator) {
    141         if ((*interator)->sessionId == sessionId) {
    142             ret = (*interator);
    143             break;
    144         }
    145     }
    146     return ret;
    147 }
    148 
    149 
    150 //------------------------------------------------------------------------------
    151 mcResult_t Device::allocateContiguousWsm(uint32_t len, CWsm **wsm)
    152 {
    153     // Allocate shared memory
    154     addr_t    virtAddr;
    155     uint32_t  handle;
    156     addr_t    physAddr;
    157     mcResult_t  ret;
    158 
    159     assert(wsm != NULL);
    160 
    161     if (!len) {
    162         return MC_DRV_ERR_INVALID_LENGTH;
    163     }
    164 
    165     ret = pMcKMod->mapWsm(len, &handle, &virtAddr, &physAddr);
    166     if (ret) {
    167         return ret;
    168     }
    169 
    170     LOG_I(" mapped handle %d to %p, phys=%p ", handle, virtAddr, physAddr);
    171 
    172     // Register (vaddr,paddr) with device
    173     *wsm = new CWsm(virtAddr, len, handle, physAddr);
    174 
    175     wsmL2List.push_back(*wsm);
    176 
    177     // Return pointer to the allocated memory
    178     return MC_DRV_OK;
    179 }
    180 
    181 
    182 //------------------------------------------------------------------------------
    183 mcResult_t Device::freeContiguousWsm(CWsm_ptr  pWsm)
    184 {
    185     mcResult_t ret = MC_DRV_ERR_WSM_NOT_FOUND;
    186     wsmIterator_t iterator;
    187 
    188     for (iterator = wsmL2List.begin(); iterator != wsmL2List.end(); ++iterator) {
    189         if (pWsm == *iterator) {
    190             ret = MC_DRV_OK;
    191             break;
    192         }
    193     }
    194     // We just looked this up using findContiguousWsm
    195     assert(ret == MC_DRV_OK);
    196 
    197     LOG_I(" unmapping handle %d from %p, phys=%p",
    198           pWsm->handle, pWsm->virtAddr, pWsm->physAddr);
    199 
    200     ret = pMcKMod->free(pWsm->handle, pWsm->virtAddr, pWsm->len);
    201     if (ret != MC_DRV_OK) {
    202         // developer forgot to free all references of this memory, we do not remove the reference here
    203         return ret;
    204     }
    205 
    206     iterator = wsmL2List.erase(iterator);
    207     delete pWsm;
    208 
    209     return ret;
    210 }
    211 
    212 
    213 //------------------------------------------------------------------------------
    214 CWsm_ptr Device::findContiguousWsm(addr_t  virtAddr)
    215 {
    216     CWsm_ptr pWsm = NULL;
    217 
    218     for ( wsmIterator_t iterator = wsmL2List.begin();
    219             iterator != wsmL2List.end();
    220             ++iterator) {
    221         CWsm_ptr pTmpWsm = *iterator;
    222         if (virtAddr == pTmpWsm->virtAddr) {
    223             pWsm = pTmpWsm;
    224             break;
    225         }
    226     }
    227 
    228     return pWsm;
    229 }
    230 
    231 /** @} */
    232