five resources associated with three contexts) were sufficient to capture the maximum level of adaptation needed by the Conference Application.
7.3
Future Work
The work presented in this thesis establishes a theoretical foundation of middleware prim- itives for enhancing the development and execution of context-aware mobile applications. Based on this model, future developments include the following.
Improvement of Current Model
Our current model can be improved in several respects:
• Although our definition of context is general enough to capture any resource avail- able in the physical environment, we have mainly exploited a view of context that is local to the device, that is, it includes the information gathered from locally available sensors only. When broadening this view outside the physical device, to include context information gathered from any peer directly (or indirectly) con- nected, other issues arise; in particular, it becomes necessary to deal with the bind- ing and re-binding of external sensors while on the move. In [Roman et al., 2002, Julien and Roman, 2002], a middleware that tackles the issues of a broad definition and maintenance of context has been presented; however, a final solution to the binding problem has not yet been found.
• To accommodate dynamicity requirements, services and policies may be installed and uninstalled on the fly; moreover, different application needs may result in dif- ferent system configurations that vary over time. The changing interactions among distributed services and policies may alter the semantics of the applications built on top of our reflective middleware. The development of safe customisable middleware therefore becomes an issue. A first step towards the definition of a formal seman- tics for specifying and reasoning about the properties of, and interactions among, middleware components can be found in [Venkatasubramanian and Talcott, 1995]. These principles have been used, for example, in [Venkatasubramanian et al., 2001] to manage changes in large-scale distributed systems while ensuring application QoS requirements. The principles they use are based on a two-level architecture where the application, at the base level, interacts with the middleware, at the meta-level, via middleware-defined core services that are then used to initiate other activities. The similarity of this approach with our architecture makes us think that similar principles could be investigated to develop a formal semantics of composition within our reflective middleware framework.
Chapter 7 7.3 Future Work
An alternative may be to use an architectural approach: an architecture specification, containing constraints about how components are composed, is provided. During the system lifetime, the run-time architecture enforces that insertion and removal of components do not violate these constraints. Early work in this area can be found in [Georgiadis et al., 2002]. They propose to associate configuration managers with each component; these managers are in charge of verifying architectural constraints each time the configuration changes (because of, for example, component join/leave events, or because of binding/unbinding actions taken by component managers). Many research issues remain open in this direction; for example, the dynamic nature of the architectural constraints must be taken into account.
• Although we have paid little attention to the communication issue, it is important to state that the message-passing communication paradigm we provide needs to be improved, as it does not support persistence of message queues (i.e., it does not support disconnections). An important engineering exercise would be, therefore, to integrate available implementations of the Java Message Service for mobile settings, for example [Softwired, 2002], within our middleware. Currently available imple- mentations, however, only target nomadic networks; an important research issue would be to port them to ad-hoc settings too.
Increased Flexibility through Logical Mobility
Despite being a very powerful concept, reflection enables adaptability and flexibility only in those contexts that middleware designers have considered likely to be unstable at design time. However, in a mobile ad-hoc setting, mobile hosts cannot forecast all the possible contexts they are going to encounter, and therefore which behaviours (i.e., policies) they are going to need. New behaviours may be delivered from time to time to cope with unforeseen context configurations and new application needs.
A major future direction of research is to exploit mobile code techniques to overcome this limitation, for example, by downloading new protocols either from a service provider or from other peers within reach that use the same behaviour [Capra et al., 2001c] [Zachariadis et al., 2002]. Moreover, only a minimum set of behaviours can be stored on a device so as to avoid consuming memory; by exchanging information about what services, code and resources are available with other peers, different behaviours can be downloaded only when needed (if needed). Reflection can be combined with mobile code techniques to allow applications to select where to download protocols from, based on application-specific information (e.g., trusted hosts, quality-of-service parameters, etc.).
Chapter 7 7.3 Future Work
QoS-aware Service Discovery and Delivery
Another major direction of research is service discovery and delivery. Traditional nam- ing and trading service discovery techniques developed for fixed distributed systems can- not be successfully applied in mobile settings, where intermittent rather than contin- uous network connection is the norm. However, service discovery for mobile settings has not yet gained significant attention. Two notable exceptions are the Jini specifica- tion [Arnold et al., 1999] and the work by Handorean and Roman [Handorean and Roman, 2002]. A disadvantage of both approaches is that they do not take quality-of-service requirements into account when deciding which service to use. We believe that QoS-aware service discovery would fit naturally in our framework, where application needs are made explicit and used to decide how a service should be delivered in the current context. Currently, these needs are taken into account only locally; a future direction of research would be to make use of this information to discover services available in an entire ad-hoc network that would deliver to the user the best QoS, according to current user-specific requirements.
Appendix A
Reflective API Semantics
A.1
Introspection
Semantics ofreadRP (Read Reactive Policy)
readRP : prof ile×P→policy∪ {null}
readRP[[(react proact, pn)]] = readRP[[(react, pn)]]
readRP[[((pn0 cL)pL, pn)]] = ( (pn0 cL) if pn=pn0 readRP[[(pL, pn)]] otherwise readRP[[(pn0 cL, pn)]] = ( (pn0 cL) if pn=pn0 null otherwise readRP[[(ε, pn)]] = null
Semantics ofreadRC (Read Reactive Context)
readRC : prof ile×P×N→context∪ {null}
readRCcl : contextList×N→context∪ {null}
readRC[[(react proact, pn, cid)]] = readRC[[(react, pn, cid)]]
readRC[[((pn0 cL)pL, pn, cid)]] =
(
readRCcl[[(cL, cid)]] if pn=pn0
readRC[[(pL, pn, cid)]] otherwise
readRC[[(pn0 cL, pn, cid)]] =
(
readRCcl[[(cL, cid)]] if pn=pn0
Appendix A A.1 Introspection
readRCcl[[((cid0 rL)cL, cid)]] = (
(cid0 rL) if cid=cid0
readRCcl[[(cL, cid)]] otherwise
readRCcl[[(cid0 rL, cid)]] = (
(cid0 rL) if cid=cid0 null otherwise
readRC[[(ε, pn, cid)]] = null
Semantics ofreadRR (Read Reactive Resource)
readRR : prof ile×P×N×R→resource∪ {null}
readRRcl : contextList×N×R→resource∪ {null}
readRRrl : resourceList×R→resource∪ {null}
readRR[[(react proact, pn, cid, rn)]] = readRR[[(react, pn, cid, rn)]]
readRR[[((pn0 cL)pL, pn, cid, rn)]] =
(
readRRcl[[(cL, cid, rn)]] if pn=pn0
readRR[[(pL, pn, cid, rn)]] otherwise
readRR[[(pn0 cL, pn, cid, rn)]] =
(
readRRcl[[(cL, cid, rn)]] if pn=pn0
null otherwise
readRRcl[[((cid0 rL)cL, cid, rn)]] = (
readRRrl[[(rL, rn)]] if cid=cid0
readRRcl[[(cL, cid, rn)]] otherwise
readRRcl[[(cid0 rL, cid, rn)]] = (
readRRrl[[(rL, rn)]] if cid=cid0
null otherwise readRRrl[[((rn on vL)rL, rn)]] = ( (rn on vL) if rn=rn0 readRRrl[[(rL, rn)]] otherwise readRRrl[[((rn on vL), rn)]] = ( (rn on vL) if rn=rn0 null otherwise
readRR[[(ε, pn, cid, rn)]] = null
Semantics ofreadP S (Read Proactive Service)
readP S : prof ile×S→service∪ {null} readP S[[(react proact, sn)]] =readP S[[(proact, sn)]]
readP S[[((sn0 pL)sL, sn)]] =
(
(sn0 pL) if sn=sn0
Appendix A A.1 Introspection readP S[[(sn0 pL, sn)]] = ( (sn0 pL) if sn=sn0 null otherwise readP S[[(ε, sn)]] =null
Semantics ofreadP P (Read Proactive Policy)
readP P : prof ile×S×P→policy∪ {null}
readP Ppl : policyList×P→policy∪ {null}
readP P[[(react proact, sn, pn)]] =readP P[[(proact, sn, pn)]]
readP P[[((sn0 pL)sL, sn, pn)]] = ( readP Ppl[[(pL, pn)]] if sn=sn0 readP P[[(sL, sn, pn)]] otherwise readP P[[(sn0 pL, sn, pn)]] = ( readP Ppl[[(pL, pn)]] if sn=sn0 null otherwise readP Ppl[[((pn0 cL)pL, pn)]] = ( (pn0 cL) if pn=pn0 readP Ppl[[(pL, pn)]] otherwise readP Ppl[[(pn0 cL, pn)]] = ( (pn0 cL) if pn=pn0 null otherwise readP P[[(ε, sn, pn)]] =null
Semantics ofreadP C (Read Proactive Context)
readP C : prof ile×S×P×N→context∪ {null}
readP Cpl : policyList×P×N→context∪ {null}
readP Ccl : contextList×N→context∪ {null}
readP C[[(react proact, sn, pn, cid)]] =readP C[[(proact, sn, pn, cid)]]
readP C[[((sn0 pL)sL, sn, pn, cid)]] =
(
readP Cpl[[(pL, pn, cid)]] if sn =sn0
readP C[[(sL, sn, pn, cid)]] otherwise
readP C[[(sn0 pL, sn, pn, cid)]] = ( readP Cpl[[(pL, pn, cid)]] if sn =sn0 null otherwise readP Cpl[[((pn0 cL)pL, pn, cid)]] = ( readP Ccl[[(cL, cid)]] if pn=pn0
Appendix A A.1 Introspection
readP Cpl[[(pn0 cL, pn, cid)]] = (
readP Ccl[[(cL, cid)]] if pn=pn0
null otherwise
readP Ccl[[((cid0 rL)cL, cid)]] = (
(cid0 rL) if cid=cid0
readP Ccl[[(cL, cid)]] otherwise
readP Ccl[[(cid0 rL, cid)]] = (
(cid0 rL) if cid=cid0 null otherwise
readP C[[(ε, sn, pn, cid)]] =null
Semantics ofreadP R(Read Proactive Resource)
readP R : prof ile×S×P×N×R→resource∪ {null}
readP Rpl : policyList×P×N×R→resource∪ {null}
readP Rcl : contextList×N×R→resource∪ {null}
readP Rrl : resourceList×R→resource∪ {null}
readP R[[(react proact, sn, pn, cid, rn)]] = readP R[[(proact, sn, pn, cid, rn)]]
readP R[[((sn0 pL)sL, sn, pn, cid, rn)]] =
(
readP Rpl[[(pL, pn, cid, rn)]] if sn=sn0
readP R[[(sL, sn, pn, cid, rn)]] otherwise
readP R[[(sn0 pL, sn, pn, cid, rn)]] = ( readP Rpl[[(pL, pn, cid, rn)]] if sn=sn0 null otherwise readP Rpl[[((pn0 cL)pL, pn, cid, rn)]] = ( readP Rcl[[(cL, cid, rn)]] if pn=pn0
readP Rpl[[(pL, pn, cid, rn)]] otherwise
readP Rpl[[(pn0 cL, pn, cid, rn)]] = (
readP Rcl[[(cL, cid, rn)]] if pn=pn0
null otherwise
readP Rcl[[((cid0 rL)cL, cid, rn)]] = (
readP Rrl[[(rL, rn)]] if cid=cid0
readP Rcl[[(cL, cid, rn)]] otherwise
readP Rcl[[(cid0 rL, cid, rn)]] = (
readP Rrl[[(rL, rn)]] if cid=cid0
null otherwise readP Rrl[[((rn on vL)rL, rn)]] = ( (rn on vL) if rn=rn0 readP Rrl[[(rL, rn)]] otherwise readP Rrl[[((rn on vL), rn)]] = ( (rn on vL) if rn=rn0 null otherwise