Modules/UDI - MEI working, used for nic
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / udi_lib / core / mei.c
index e92afce..e0caec7 100644 (file)
@@ -5,12 +5,88 @@
  * udi_lib/mei.c
  * - Metalanguage-to-Environment Interface
  */
+#define DEBUG  1
 #include <udi.h>
 #include <acess.h>
+#include <udi_internal.h>
+
+typedef struct {
+       tUDI_DeferredCall       DCall;
+       const udi_mei_op_template_t     *mei_op;
+} tUDI_MeiCall;
 
 // === CODE ===
+void _udi_mei_call_unmarshal(tUDI_DeferredCall *DCall)
+{
+       tUDI_MeiCall    *Call = (void*)DCall;
+       const udi_mei_op_template_t     *mei_op = Call->mei_op;
+       mei_op->backend_stub(Call->DCall.Handler, Call->DCall.cb, Call+1);
+}
+
 void udi_mei_call(udi_cb_t *gcb, udi_mei_init_t *meta_info, udi_index_t meta_ops_num, udi_index_t vec_idx, ...)
 {
-       UNIMPLEMENTED();
+       ENTER("pgcb pmeta_info imeta_ops_num ivec_idx",
+               gcb, meta_info, meta_ops_num, vec_idx);
+       const udi_mei_op_template_t     *mei_op;
+
+       {
+               udi_mei_ops_vec_template_t      *ops = meta_info->ops_vec_template_list;
+               for( ; ops->meta_ops_num && ops->meta_ops_num != meta_ops_num; ops ++ )
+                       ;
+               if( !ops->meta_ops_num ) {
+                       LEAVE('-');
+                       return ;
+               }
+               mei_op = &ops->op_template_list[vec_idx-1];
+       }
+       
+       LOG("%s", mei_op->op_name);
+
+       // Check CB type
+       udi_index_t     cb_type;
+       tUDI_MetaLang   *metalang = UDI_int_GetCbType(gcb, &cb_type);
+       //if( metalang->MeiInfo != meta_info )
+       //      return ;
+       if( mei_op->meta_cb_num != cb_type ) {
+               LEAVE('-');
+               return ;
+       }
+       // Check call type
+       udi_op_t        *const*ops = UDI_int_ChannelPrepForCall(gcb, metalang, meta_ops_num);
+       udi_op_t        *op = ops[vec_idx];
+       
+       // Start va_args
+       // Determine if indirect call is needed
+       // > check stack depth?
+       // > Direction?
+        int indirect_call = (mei_op->op_category == UDI_MEI_OPCAT_REQ)
+               || (mei_op->op_category == UDI_MEI_OPCAT_IND);
+       if( indirect_call )
+       {
+               va_list args;
+               va_start(args, vec_idx);
+               size_t  marshal_size = _udi_marshal_values(NULL, mei_op->marshal_layout, args);
+               va_end(args);
+               tUDI_MeiCall    *call = malloc(sizeof(tUDI_MeiCall) + marshal_size);
+               call->DCall.Next = NULL;
+               call->DCall.Unmarshal = _udi_mei_call_unmarshal;
+               call->DCall.cb = gcb;
+               call->DCall.Handler = op;
+               call->mei_op = mei_op;
+               void    *marshal_space = (void*)(call+1);
+               va_start(args, vec_idx);
+               _udi_marshal_values(marshal_space, mei_op->marshal_layout, args);
+               va_end(args);
+               
+               UDI_int_AddDeferred(&call->DCall);
+       }
+       else
+       {
+               va_list args;
+               va_start(args, vec_idx);
+               mei_op->direct_stub( op, gcb, args );
+               va_end(args);
+       }
+       LEAVE('-');
 }
 

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