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