• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //------------------------------------------------------------------------------
Device(uint32_t deviceId,Connection * connection)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 //------------------------------------------------------------------------------
~Device(void)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 //------------------------------------------------------------------------------
open(const char * deviceName)84 bool Device::open(const char *deviceName)
85 {
86     return pMcKMod->open(deviceName);
87 }
88 
89 
90 //------------------------------------------------------------------------------
close(void)91 void Device::close(void)
92 {
93     pMcKMod->close();
94 }
95 
96 
97 //------------------------------------------------------------------------------
hasSessions(void)98 bool Device::hasSessions(void)
99 {
100     return sessionList.size() > 0;
101 }
102 
103 
104 //------------------------------------------------------------------------------
createNewSession(uint32_t sessionId,Connection * connection)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 //------------------------------------------------------------------------------
removeSession(uint32_t sessionId)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 //------------------------------------------------------------------------------
resolveSessionId(uint32_t sessionId)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 //------------------------------------------------------------------------------
allocateContiguousWsm(uint32_t len,CWsm ** wsm)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 //------------------------------------------------------------------------------
freeContiguousWsm(CWsm_ptr pWsm)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 //------------------------------------------------------------------------------
findContiguousWsm(addr_t virtAddr)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