3 * - By John Hodge (thePowersGang)
11 #include "udi_internal.h"
13 struct sUDI_ChannelSide {
14 struct sUDI_Channel *BackPtr;
19 typedef struct sUDI_Channel
21 enum eUDI_MetaLang MetaLang;
22 udi_index_t MetaOpsNum;
23 struct sUDI_ChannelSide Side[2];
27 udi_channel_t UDI_CreateChannel(enum eUDI_MetaLang metalang, udi_index_t meta_ops_num,
28 tUDI_DriverInstance *ThisEnd, udi_index_t ThisOpsIndex,
29 tUDI_DriverInstance *OtherEnd, udi_index_t OtherOpsIndex)
31 tUDI_Channel *ret = NEW(tUDI_Channel,);
33 tUDI_DriverInstance *inst;
34 udi_index_t ops_index;
36 {ThisEnd, ThisOpsIndex},
37 {OtherEnd, OtherOpsIndex}
39 ret->MetaLang = metalang;
40 ret->MetaOpsNum = meta_ops_num;
41 for( int i = 0; i < 2; i ++ )
46 tUDI_DriverModule *mod = ends[i].inst->Module;
47 ret->Side[i].BackPtr = ret;
48 udi_ops_init_t *ops = mod->InitInfo->ops_init_list;;
49 while( ops->ops_idx && ops->ops_idx != ends[i].ops_index )
51 ASSERTR(ops->ops_idx, NULL); // TODO: Pretty error
52 ASSERTCR(ops->meta_idx, <, mod->nMetaLangs, NULL);
53 ASSERTCR(mod->MetaLangs[ops->meta_idx], ==, metalang, NULL);
54 ASSERTCR(ops->meta_ops_num, ==, meta_ops_num, NULL);
55 if( ops->chan_context_size ) {
56 ret->Side[i].Context = malloc(ops->chan_context_size);
58 ret->Side[i].Ops = ops->ops_vector;
60 return (udi_channel_t)&ret->Side[0].BackPtr;
64 * \brief Prepare a cb for a channel call
65 * \param gcb Generic control block for this request
66 * \param metalang UDI metalanguage (used for validation)
67 * \return Pointer to ops list
68 * \retval NULL Metalangage validation failed
70 * Updates the channel and context fields of the gcb, checks the metalanguage and returns
71 * the handler list for the other end of the channel.
73 const void *UDI_int_ChannelPrepForCall(udi_cb_t *gcb, enum eUDI_MetaLang metalang, udi_index_t meta_ops_num)
75 tUDI_Channel *ch = *(tUDI_Channel**)(gcb->channel);
76 ASSERTCR(ch->MetaLang, ==, metalang, NULL);
78 struct sUDI_ChannelSide *newside = (gcb->channel == (udi_channel_t)&ch->Side[0].BackPtr ? &ch->Side[1] : &ch->Side[0]);
80 // gcb->initiator_context = gcb->context;
81 gcb->channel = (udi_channel_t)&newside->BackPtr;
82 gcb->context = newside->Context;