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 COMBINE3_MOD_PID (DFLT_APP_ID0+6)
21 // The pointers to function control blocks corresponding to
22 // the output(s) should appear first in the state. Other
23 // function CB's should follow after that.
25 func_cb_ptr output0
; //!< Function control block for output port 0
26 //func_cb_ptr put_token; //!< This function control block is used in SOS_CALL
28 //!< needs to put a token on any output port.
29 //!< The output port is identified by passing
30 //!< one of the function control blocks defined
31 //!< above (output0 or output1).
32 func_cb_ptr signal_error
; //!< Used with split-phase operations to indicate
33 //!< an error to the wiring engine after accepting
37 uint8_t stored_input
[2]; //!< Global variable to hold inputs while waiting for
42 static int8_t element_module(void *state
, Message
*msg
);
43 static int8_t process_input(element_state_t
*s
, uint8_t data
);
45 // Function corresponding to the input port. Each port will
46 // have its own input function which will be published by the module.
47 // The prototypes of the input and output functions should match,
48 // else linking through the wiring engine will also not work.
49 // Since, all the input functions have a common prototype (for
50 // the indirect call through engine to work), the output
51 // functions should also have "cyC2" as their prototype.
52 // This is currently kept for simplicity, but can easily be
53 // used to enforce type checking at run-time too without any overhead.
54 // Split-phase operations should return -EBUSY after accepting
55 // an input token so that the wiring engine knows that the module
56 // will take long to complete that operation and it should queue
57 // all the tokens meant for that module till the module puts
58 // a result on any of its output ports.
59 static int8_t input0 (func_cb_ptr p
, token_type_t
*t
);
60 static int8_t input1 (func_cb_ptr p
, token_type_t
*t
);
61 static int8_t input2 (func_cb_ptr p
, token_type_t
*t
);
63 static mod_header_t mod_header SOS_MODULE_HEADER
= {
64 .mod_id
= COMBINE3_MOD_PID
,
65 .code_id
= ehtons(COMBINE3_MOD_PID
),
66 .platform_type
= HW_TYPE
,
67 .processor_type
= MCU_TYPE
,
68 .state_size
= sizeof(element_state_t
),
72 .module_handler
= element_module
,
74 {error_8
, "cyC2", COMBINE3_MOD_PID
, INVALID_GID
},
75 //{error_8, "cyC4", MULTICAST_SERV_PID, DISPATCH_FID},
76 {error_8
, "ccv1", MULTICAST_SERV_PID
, SIGNAL_ERR_FID
},
77 {input0
, "cyC2", COMBINE3_MOD_PID
, INPUT_PORT_0
},
78 {input1
, "cyC2", COMBINE3_MOD_PID
, INPUT_PORT_1
},
79 {input2
, "cyC2", COMBINE3_MOD_PID
, INPUT_PORT_2
},
83 static int8_t element_module(void *state
, Message
*msg
) {
84 element_state_t
*s
= (element_state_t
*)state
;
97 default: return -EINVAL
;
102 static int8_t process_input(element_state_t
*s
, uint8_t data
) {
105 // Get token from port.
106 // If want to break the chain of calls here, then copy the token into a private
107 // data structure(global), and return appropriate value (-EBUSY).
111 s
->stored_input
[0] = data
;
112 s
->status
= WAITING_FOR_1
;
117 s
->stored_input
[1] = data
;
118 s
->status
= WAITING_FOR_2
;
123 // Process input: Combine (OR) the three inputs and pass the result on to the next function.
124 // We need a separate place to hold the output as we are modifying the input.
125 // Remember, this module does not own the input token, so should not
127 out_value
= data
| s
->stored_input
[0] | s
->stored_input
[1];
129 DEBUG("COMBINE: Output - token %d.\n", out_value
);
130 token_type_t
*my_token
= create_token(&out_value
, sizeof(uint8_t), s
->pid
);
131 if (my_token
== NULL
) return -ENOMEM
;
132 //SOS_CALL(s->put_token, put_token_func_t, s->output0, my_token);
133 dispatch(s
->output0
, my_token
);
135 destroy_token(my_token
);
138 default: return SOS_OK
;
144 //--------------------------------------------------------
146 static int8_t input0 (func_cb_ptr p
, token_type_t
*t
) {
147 element_state_t
*s
= (element_state_t
*)sys_get_state();
148 DEBUG("COMBINE: Accept - token %d on input 0.\n", *((uint8_t *)get_token_data(t
)));
149 return process_input(s
, *((uint8_t *)get_token_data(t
)));
152 static int8_t input1 (func_cb_ptr p
, token_type_t
*t
) {
153 element_state_t
*s
= (element_state_t
*)sys_get_state();
154 DEBUG("COMBINE: Accept - token %d on input 1.\n", *((uint8_t *)get_token_data(t
)));
155 return process_input(s
, *((uint8_t *)get_token_data(t
)));
158 static int8_t input2 (func_cb_ptr p
, token_type_t
*t
) {
159 element_state_t
*s
= (element_state_t
*)sys_get_state();
160 DEBUG("COMBINE: Accept - token %d on input 2.\n", *((uint8_t *)get_token_data(t
)));
161 return process_input(s
, *((uint8_t *)get_token_data(t
)));
164 //--------------------------------------------------------
166 mod_header_ptr
combine3_get_header()
168 return sos_get_header_address(mod_header
);