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