1/** @addtogroup MCD_IMPL_LIB
2 * @{
3 * @file
4 * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote
15 *    products derived from this software without specific prior
16 *    written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30#include <stdint.h>
31#include <vector>
32
33#include "mc_linux.h"
34
35#include "Session.h"
36
37#include "log.h"
38#include <assert.h>
39
40
41//------------------------------------------------------------------------------
42Session::Session(
43    uint32_t    sessionId,
44    CMcKMod     *mcKMod,
45    Connection  *connection)
46{
47    this->sessionId = sessionId;
48    this->mcKMod = mcKMod;
49    this->notificationConnection = connection;
50
51    sessionInfo.lastErr = SESSION_ERR_NO;
52    sessionInfo.state = SESSION_STATE_INITIAL;
53}
54
55
56//------------------------------------------------------------------------------
57Session::~Session(void)
58{
59    BulkBufferDescriptor  *pBlkBufDescr;
60
61    // Unmap still mapped buffers
62    for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin();
63            iterator != bulkBufferDescriptors.end();
64            ++iterator) {
65        pBlkBufDescr = *iterator;
66
67        LOG_I("removeBulkBuf - Physical Address of L2 Table = 0x%X, handle= %d",
68              (unsigned int)pBlkBufDescr->physAddrWsmL2,
69              pBlkBufDescr->handle);
70
71        // ignore any error, as we cannot do anything in this case.
72        int ret = mcKMod->unregisterWsmL2(pBlkBufDescr->handle);
73        if (ret != 0) {
74            LOG_E("removeBulkBuf(): mcKModUnregisterWsmL2 failed: %d", ret);
75        }
76
77        //iterator = bulkBufferDescriptors.erase(iterator);
78        delete(pBlkBufDescr);
79    }
80
81    // Finally delete notification connection
82    delete notificationConnection;
83
84    unlock();
85}
86
87
88//------------------------------------------------------------------------------
89void Session::setErrorInfo(
90    int32_t err
91)
92{
93    sessionInfo.lastErr = err;
94}
95
96
97//------------------------------------------------------------------------------
98int32_t Session::getLastErr(
99    void
100)
101{
102    return sessionInfo.lastErr;
103}
104
105
106//------------------------------------------------------------------------------
107mcResult_t Session::addBulkBuf(addr_t buf, uint32_t len, BulkBufferDescriptor **blkBuf)
108{
109    addr_t pPhysWsmL2;
110    uint32_t handle;
111
112    assert(blkBuf != NULL);
113
114    // Search bulk buffer descriptors for existing vAddr
115    // At the moment a virtual address can only be added one time
116    for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin();
117            iterator != bulkBufferDescriptors.end();
118            ++iterator) {
119        if ((*iterator)->virtAddr == buf) {
120            LOG_E("Cannot map a buffer to multiple locations in one Trustlet.");
121            return MC_DRV_ERR_BUFFER_ALREADY_MAPPED;
122        }
123    }
124
125    // Prepare the interface structure for memory registration in Kernel Module
126    mcResult_t ret = mcKMod->registerWsmL2(buf, len, 0, &handle, &pPhysWsmL2);
127
128    if (ret != MC_DRV_OK) {
129        LOG_V(" mcKMod->registerWsmL2() failed with %x", ret);
130        return ret;
131    }
132
133    LOG_V(" addBulkBuf - Handle of L2 Table = %u", handle);
134
135    // Create new descriptor - secure virtual virtual set to 0, unknown!
136    *blkBuf = new BulkBufferDescriptor(buf, 0x0, len, handle, pPhysWsmL2);
137
138    // Add to vector of descriptors
139    bulkBufferDescriptors.push_back(*blkBuf);
140
141    return MC_DRV_OK;
142}
143
144//------------------------------------------------------------------------------
145uint32_t Session::getBufHandle(addr_t sVirtAddr)
146{
147    LOG_V("getBufHandle(): Virtual Address = 0x%X", (unsigned int) virtAddr);
148
149    // Search and remove bulk buffer descriptor
150    for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin();
151            iterator != bulkBufferDescriptors.end();
152            ++iterator ) {
153        if ((*iterator)->sVirtualAddr == sVirtAddr) {
154            return (*iterator)->handle;
155        }
156    }
157    return 0;
158}
159
160//------------------------------------------------------------------------------
161mcResult_t Session::removeBulkBuf(addr_t virtAddr)
162{
163    BulkBufferDescriptor  *pBlkBufDescr = NULL;
164
165    LOG_V("removeBulkBuf(): Virtual Address = 0x%X", (unsigned int) virtAddr);
166
167    // Search and remove bulk buffer descriptor
168    for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin();
169            iterator != bulkBufferDescriptors.end();
170            ++iterator
171        ) {
172
173        if ((*iterator)->virtAddr == virtAddr) {
174            pBlkBufDescr = *iterator;
175            iterator = bulkBufferDescriptors.erase(iterator);
176            break;
177        }
178    }
179
180    if (pBlkBufDescr == NULL) {
181        LOG_E("%p not registered in session %d.", virtAddr, sessionId);
182        return MC_DRV_ERR_BLK_BUFF_NOT_FOUND;
183    }
184    LOG_V("removeBulkBuf():handle=%u", pBlkBufDescr->handle);
185
186    // ignore any error, as we cannot do anything
187    mcResult_t ret = mcKMod->unregisterWsmL2(pBlkBufDescr->handle);
188    if (ret != MC_DRV_OK) {
189        LOG_E("mcKMod->unregisterWsmL2 failed: %x", ret);
190        return ret;
191    }
192
193    delete (pBlkBufDescr);
194
195    return MC_DRV_OK;
196}
197
198/** @} */
199