-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsolver_dispatch.c
140 lines (134 loc) · 3.85 KB
/
solver_dispatch.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*!
* MPT solver library
* setup event controller for solver events
*/
#include "message.h"
#include "event.h"
#include "client.h"
#include "config.h"
#include "solver.h"
static MPT_INTERFACE(config) *getConfig(MPT_INTERFACE(client) *cl, MPT_INTERFACE(reply_context) *rc)
{
MPT_INTERFACE(config) *cfg = 0;
if (cl->_vptr->meta.convertable.convert((void *) cl, MPT_ENUM(TypeConfigPtr), &cfg) > 0
&& cfg) {
return cfg;
}
mpt_context_reply(rc, MPT_ERROR(BadType), "%s",
MPT_tr("client without config interface"));
return cfg;
}
static int setConf(void *ptr, const MPT_STRUCT(path) *p, const MPT_STRUCT(value) *val)
{
MPT_INTERFACE(config) *cfg = ptr;
return cfg->_vptr->assign(cfg, p, val);
}
static int condConf(void *ptr, const MPT_STRUCT(path) *p, const MPT_STRUCT(value) *val)
{
MPT_INTERFACE(config) *cfg = ptr;
int ret;
if (cfg->_vptr->query(cfg, p, 0, 0) >= 0) {
return 0;
}
ret = cfg->_vptr->assign(cfg, p, val);
return ret ? ret : 1;
}
/*!
* \ingroup mptSolver
* \brief process command event
*
* Call client command process function with
* content in event message data.
* Set command as default event type if client requests
* default operation.
*
* \param dsp dispatch descriptor
* \param ev client descriptor
*
* \retval 0 success
* \retval -1 missing descriptor pointer
*/
extern int mpt_solver_dispatch(MPT_INTERFACE(client) *cl, MPT_STRUCT(event) *ev)
{
MPT_STRUCT(message) tmp;
MPT_STRUCT(msgtype) mt;
int ret;
if (!ev) {
return 0;
}
if (!ev->msg) {
return MPT_event_fail(ev, MPT_ERROR(BadArgument), MPT_tr("no default action"));
}
tmp = *ev->msg;
/* get message header */
mt.arg = 0;
if (!(ret = mpt_message_read(&tmp, sizeof(mt), &mt))) {
return MPT_event_fail(ev, MPT_ERROR(MissingData), MPT_tr("empty message"));
}
/* process parameter data */
if (mt.cmd == MPT_MESGTYPE(ParamGet)) {
MPT_INTERFACE(config) *cfg;
if (!(cfg = getConfig(cl, ev->reply))) {
return MPT_EVENTFLAG(Fail);
}
ret = mpt_config_reply(ev->reply, cfg, mt.arg, &tmp);
if (ret < 0) {
return MPT_event_fail(ev, ret, MPT_tr("parameter collection failed"));
}
return MPT_EVENTFLAG(None);
}
if (mt.cmd == MPT_MESGTYPE(ParamSet)) {
MPT_INTERFACE(config) *cfg;
if (!(cfg = getConfig(cl, ev->reply))) {
return MPT_EVENTFLAG(Fail);
}
ret = mpt_message_assign(&tmp, mt.arg, setConf, cfg);
if (ret < 0) {
return MPT_event_fail(ev, ret, MPT_tr("parameter assignment failed"));
}
return MPT_event_good(ev, MPT_tr("parameter assigned"));
}
if (mt.cmd == MPT_MESGTYPE(ParamCond)) {
MPT_INTERFACE(config) *cfg;
if (!(cfg = getConfig(cl, ev->reply))) {
return MPT_EVENTFLAG(Fail);
}
ret = mpt_message_assign(&tmp, mt.arg, condConf, cfg);
if (ret < 0) {
return MPT_event_fail(ev, ret, MPT_tr("parameter assignment failed"));
}
if (!ret) {
return MPT_event_good(ev, MPT_tr("parameter unchanged"));
} else {
return MPT_event_good(ev, MPT_tr("parameter assigned"));
}
}
/* require command message */
if (mt.cmd != MPT_MESGTYPE(Command)) {
mpt_context_reply(ev->reply, MPT_ERROR(BadArgument), "%s (%02x != %02x)",
MPT_tr("invalid message type"), mt.cmd, MPT_MESGTYPE(Command));
return MPT_EVENTFLAG(Fail);
}
if (ret < (int) sizeof(mt)) {
ret = cl->_vptr->process(cl, mt.cmd, 0);
} else {
ret = mpt_client_command(cl, &tmp, mt.arg);
}
if (ret < 0) {
return MPT_event_fail(ev, ret, MPT_tr("command processing failed"));
}
if (ret & MPT_EVENTFLAG(Fail)) {
if (ret & MPT_EVENTFLAG(Default)) {
ev->id = 0;
}
mpt_context_reply(ev->reply, MPT_ERROR(BadOperation), "%s", MPT_tr("command processing failed"));
}
else if (ret & MPT_EVENTFLAG(Default)) {
ev->id = MPT_MESGTYPE(Command);
mpt_context_reply(ev->reply, 0, "%s", MPT_tr("set default command"));
}
else {
mpt_context_reply(ev->reply, 0, "%s", MPT_tr("command processing successful"));
}
return ret;
}