1 /* -*- Mode: C; tab-width:4 -*- */
2 /* ex: set ts=4 shiftwidth=4 softtabstop=4 cindent: */
5 #include <sys_module.h>
6 #include <wiring_config.h>
12 #define COMBINE_MOD_PID (DFLT_APP_ID0+5)
20 // The pointers to function control blocks corresponding to
21 // the output(s) should appear first in the state. Other
22 // function CB's should follow after that.
24 func_cb_ptr output0
; //!< Function control block for output port 0
25 //func_cb_ptr put_token; //!< This function control block is used in SOS_CALL
27 //!< needs to put a token on any output port.
28 //!< The output port is identified by passing
29 //!< one of the function control blocks defined
30 //!< above (output0 or output1).
31 func_cb_ptr signal_error
; //!< Used with split-phase operations to indicate
32 //!< an error to the wiring engine after accepting
36 uint8_t stored_input
; //!< Global variable to hold one input while waiting for
40 static int8_t element_module(void *state
, Message
*msg
);
42 // Function corresponding to the input port. Each port will
43 // have its own input function which will be published by the module.
44 // The prototypes of the input and output functions should match,
45 // else linking through the wiring engine will also not work.
46 // Since, all the input functions have a common prototype (for
47 // the indirect call through engine to work), the output
48 // functions should also have "cyC2" as their prototype.
49 // This is currently kept for simplicity, but can easily be
50 // used to enforce type checking at run-time too without any overhead.
51 // Split-phase operations should return -EBUSY after accepting
52 // an input token so that the wiring engine knows that the module
53 // will take long to complete that operation and it should queue
54 // all the tokens meant for that module till the module puts
55 // a result on any of its output ports.
56 //static int8_t input0 (func_cb_ptr p, void *data, uint16_t length);
57 //static int8_t input1 (func_cb_ptr p, void *data, uint16_t length);
58 static int8_t input0 (func_cb_ptr p
, token_type_t
*t
);
59 static int8_t input1 (func_cb_ptr p
, token_type_t
*t
);
61 static mod_header_t mod_header SOS_MODULE_HEADER
= {
62 .mod_id
= COMBINE_MOD_PID
,
63 .code_id
= ehtons(COMBINE_MOD_PID
),
64 .platform_type
= HW_TYPE
,
65 .processor_type
= MCU_TYPE
,
66 .state_size
= sizeof(element_state_t
),
70 .module_handler
= element_module
,
72 {error_8
, "cyC2", COMBINE_MOD_PID
, INVALID_GID
},
73 //{error_8, "cyC4", MULTICAST_SERV_PID, DISPATCH_FID},
74 {error_8
, "ccv1", MULTICAST_SERV_PID
, SIGNAL_ERR_FID
},
75 {input0
, "cyC2", COMBINE_MOD_PID
, INPUT_PORT_0
},
76 {input1
, "cyC2", COMBINE_MOD_PID
, INPUT_PORT_1
},
80 static int8_t element_module(void *state
, Message
*msg
) {
81 element_state_t
*s
= (element_state_t
*)state
;
95 default: return -EINVAL
;
100 //--------------------------------------------------------
101 static int8_t process_input(element_state_t
*s
, uint8_t data
) {
105 s
->stored_input
= data
;
111 // Process input: Combine (OR) the two inputs and pass the result on to the next function.
112 // We need a separate place to hold the output as we are modifying the input.
113 // Remember, this module does not own the input token, so should not
115 uint8_t out_value
= data
| s
->stored_input
;
116 token_type_t
*my_token
= create_token(&out_value
, sizeof(uint8_t), s
->pid
);
117 if (my_token
== NULL
) return -ENOMEM
;
118 //SOS_CALL(s->put_token, put_token_func_t, s->output0, my_token);
119 dispatch(s
->output0
, my_token
);
121 destroy_token(my_token
);
131 static int8_t input0 (func_cb_ptr p
, token_type_t
*t
) {
132 element_state_t
*s
= (element_state_t
*)sys_get_state();
134 return process_input(s
, *((uint8_t *)get_token_data(t
)));
137 static int8_t input1 (func_cb_ptr p
, token_type_t
*t
) {
138 element_state_t
*s
= (element_state_t
*)sys_get_state();
140 return process_input(s
, *((uint8_t *)get_token_data(t
)));
143 //--------------------------------------------------------
145 mod_header_ptr
combine_get_header()
147 return sos_get_header_address(mod_header
);