@@ -29,21 +29,39 @@ static char * m_interface = NULL;
29
29
/** Bus slot used to register the Vtable */
30
30
static sd_bus_slot * m_slot = NULL ;
31
31
32
+ /** Max mtu size of sink */
33
+ static size_t m_max_mtu ;
34
+
35
+ /* Max number of downlink packet being sent in parallel */
36
+ static size_t m_downlink_limit ;
37
+
32
38
/**********************************************************************
33
39
* DBUS Methods implementation *
34
40
**********************************************************************/
41
+
42
+ static uint8_t m_message_queued_in_sink = 0 ;
43
+
44
+ static void on_data_sent_cb (uint16_t pduid , uint32_t buffering_delay , uint8_t result )
45
+ {
46
+ m_message_queued_in_sink -= (uint8_t ) (pduid >> 8 );
47
+ LOGD ("Message sent %d, Message_queued: %d\n" , pduid , m_message_queued_in_sink );
48
+ }
49
+
35
50
/**
36
51
* \brief Send a message handler
37
52
* \param ... (from sd_bus function signature)
38
53
*/
39
54
static int send_message (sd_bus_message * m , void * userdata , sd_bus_error * error )
40
55
{
56
+ static uint8_t m_pdu_id = 0 ;
57
+
41
58
app_message_t message ;
42
59
app_res_e res ;
43
60
const void * data ;
44
61
size_t n ;
45
62
int r ;
46
63
uint8_t qos ;
64
+ uint8_t weight ;
47
65
48
66
/* Read the parameters */
49
67
r = sd_bus_message_read (m ,
@@ -77,21 +95,46 @@ static int send_message(sd_bus_message * m, void * userdata, sd_bus_error * erro
77
95
message .bytes = data ;
78
96
message .num_bytes = n ;
79
97
98
+ if (m_downlink_limit > 0 )
99
+ {
100
+ /* Check if message can be queued */
101
+ weight = (n + m_max_mtu - 1 ) / m_max_mtu ;
102
+ if (m_message_queued_in_sink + weight > m_downlink_limit )
103
+ {
104
+ // No point to try sending data, queue is already full
105
+ return sd_bus_reply_method_return (m , "u" , APP_RES_OUT_OF_MEMORY );
106
+ }
107
+
108
+ /* Keep track of packet queued on the sink */
109
+ /* Encode weight in ID */
110
+ message .pdu_id = weight << 8 | m_pdu_id ++ ;
111
+ message .on_data_sent_cb = on_data_sent_cb ;
112
+ }
113
+ else
114
+ {
115
+ message .pdu_id = 0 ;
116
+ message .on_data_sent_cb = NULL ;
117
+
118
+ }
119
+
80
120
LOGD ("Message to send on EP %d from EP %d to 0x%x size = %d\n" ,
81
121
message .dst_ep ,
82
122
message .src_ep ,
83
123
message .dst_addr ,
84
124
message .num_bytes );
85
125
86
- /* Send packet. For now, packets are not tracked to keep behavior simpler */
87
- message .pdu_id = 0 ;
88
- message .on_data_sent_cb = NULL ;
126
+
89
127
90
128
res = WPC_send_data_with_options (& message );
91
129
if (res != APP_RES_OK )
92
130
{
93
131
LOGE ("Cannot send data: %d\n" , res );
94
132
}
133
+ else if (m_downlink_limit > 0 )
134
+ {
135
+ m_message_queued_in_sink += weight ;
136
+ LOGI ("Message_queued: %d\n" , m_message_queued_in_sink );
137
+ }
95
138
96
139
return sd_bus_reply_method_return (m , "u" , res );
97
140
}
@@ -203,17 +246,24 @@ static const sd_bus_vtable data_vtable[] = {
203
246
204
247
SD_BUS_VTABLE_END };
205
248
206
- int Data_Init (sd_bus * bus , char * object , char * interface )
249
+ int Data_Init (sd_bus * bus , char * object , char * interface , size_t downlink_limit )
207
250
{
208
251
int ret ;
209
252
210
253
m_bus = bus ;
211
254
m_object = object ;
212
255
m_interface = interface ;
256
+ m_downlink_limit = downlink_limit ;
213
257
214
258
/* Register for all data */
215
259
WPC_register_for_data (onDataReceived );
216
260
261
+ if (WPC_get_mtu ((uint8_t * ) & m_max_mtu ) != APP_RES_OK )
262
+ {
263
+ LOGW ("Cannot read max mtu from node" );
264
+ m_max_mtu = 102 ;
265
+ }
266
+
217
267
/* Install the data vtable */
218
268
ret = sd_bus_add_object_vtable (bus , & m_slot , object , interface , data_vtable , NULL );
219
269
if (ret < 0 )
0 commit comments