Modules/UDI - Channel code implimented (partially)
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / channels.c
index e173747..d232e03 100644 (file)
@@ -1,6 +1,9 @@
 /*
  * Acess2 UDI Layer
  * - By John Hodge (thePowersGang)
+ *
+ * channels.c
+ * - Channel code
  */
 #define DEBUG  0
 #include <acess.h>
@@ -16,6 +19,7 @@ struct sUDI_ChannelSide {
 typedef struct sUDI_Channel
 {
        enum eUDI_MetaLang      MetaLang;
+       udi_index_t     MetaOpsNum;
        struct sUDI_ChannelSide  Side[2];
 } tUDI_Channel;
 
@@ -25,14 +29,48 @@ udi_channel_t UDI_CreateChannel(enum eUDI_MetaLang metalang, udi_index_t meta_op
        tUDI_DriverInstance *OtherEnd, udi_index_t OtherOpsIndex)
 {
        tUDI_Channel    *ret = NEW(tUDI_Channel,);
+       struct {
+               tUDI_DriverInstance     *inst;
+               udi_index_t     ops_index;
+       } ends[2] = {
+               {ThisEnd, ThisOpsIndex},
+               {OtherEnd, OtherOpsIndex}
+       };
        ret->MetaLang = metalang;
-       ret->Side[0].BackPtr = ret;
-//     ret->Side[0].Ops = ThisEnd->Module->InitInfo->Op;
-       ret->Side[1].BackPtr = ret;
+       ret->MetaOpsNum = meta_ops_num;
+       for( int i = 0; i < 2; i ++ )
+       {
+               if( !ends[i].inst ) {
+                       continue ;
+               }
+               tUDI_DriverModule       *mod = ends[i].inst->Module;
+               ret->Side[i].BackPtr = ret;
+               udi_ops_init_t  *ops = mod->InitInfo->ops_init_list;;
+               while( ops->ops_idx && ops->ops_idx != ends[i].ops_index )
+                       ops++;
+               ASSERTR(ops->ops_idx, NULL);    // TODO: Pretty error
+               ASSERTCR(ops->meta_idx, <, mod->nMetaLangs, NULL);
+               ASSERTCR(mod->MetaLangs[ops->meta_idx], ==, metalang, NULL);
+               ASSERTCR(ops->meta_ops_num, ==, meta_ops_num, NULL);
+               if( ops->chan_context_size ) {
+                       ret->Side[i].Context = malloc(ops->chan_context_size);
+               }
+               ret->Side[i].Ops = ops->ops_vector;
+       }
        return (udi_channel_t)&ret->Side[0].BackPtr;
 }
 
-const void *UDI_int_ChannelPrepForCall(udi_cb_t *gcb, enum eUDI_MetaLang metalang)
+/**
+ * \brief Prepare a cb for a channel call
+ * \param gcb  Generic control block for this request
+ * \param metalang     UDI metalanguage (used for validation)
+ * \return Pointer to ops list
+ * \retval NULL        Metalangage validation failed
+ *
+ * Updates the channel and context fields of the gcb, checks the metalanguage and returns
+ * the handler list for the other end of the channel.
+ */
+const void *UDI_int_ChannelPrepForCall(udi_cb_t *gcb, enum eUDI_MetaLang metalang, udi_index_t meta_ops_num)
 {
        tUDI_Channel *ch = *(tUDI_Channel**)(gcb->channel);
        ASSERTCR(ch->MetaLang, ==, metalang, NULL);

UCC git Repository :: git.ucc.asn.au