2 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
4 * Contact: Suresh Kumar N (suresh.n@samsung.com)
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 #include "zigbee_service_interface_common.h"
21 #include <zblib_driver_custom.h>
24 static void *_service_interface_ref_zigbee_custom(
25 ZigBeeServiceInterface *service_interface)
27 ZigbeeObjectSkeleton *zigbee_object = NULL;
28 ZigbeeCustomData_t *custom_data = NULL;
29 ZigbeeCustom *custom_object = NULL;
31 custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
32 if (NULL == custom_data) {
33 Z_LOGE("D-BUS service interface custom_data is NULL!");
37 /* Get zigbee object */
38 zigbee_object = g_hash_table_lookup(custom_data->objects, ZIGBEE_SERVICE_PATH);
39 if (NULL == zigbee_object) {
40 Z_LOGW("Cannot find ZigBee D-BUS interface object!", zigbee_object);
44 custom_object = zigbee_object_get_custom(ZIGBEE_OBJECT(zigbee_object));
48 static void on_custom_aps_send_resp(ZigBeeServiceInterface *service_interface,
49 guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
51 ZigbeeServiceInterfaceRespCbData_t *cb_data =
52 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
54 ZigbeeCustom *custom_object = NULL;
55 GDBusMethodInvocation *invocation = NULL;
57 ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
59 NOT_USED(service_interface);
62 if (NULL == resp_data || 0 == resp_data_len) {
63 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
68 custom_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
69 zblib_check_null_free_and_ret("custom_object", custom_object, cb_data);
71 invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
72 zblib_check_null_free_and_ret("invocation", invocation, cb_data);
74 zigbee_custom_complete_aps_send(custom_object, invocation, payload->result);
79 static gboolean on_custom_aps_send(ZigbeeCustom *custom_object,
80 GDBusMethodInvocation *invocation,
94 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
95 ZigbeeCustomApsSend_t req;
96 ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
98 GVariantIter *iter = NULL;
103 memset(&req, 0x0, sizeof(ZigbeeCustomApsSend_t));
105 /* Update request structure */
106 req.node_id = node_id;
107 req.aps_frame_ctrl = aps_frame_ctrl;
109 req.dest_ep = dest_ep;
110 req.cluster_id = cluster_id;
111 req.profile_id = profile_id;
112 req.zcl_frame_ctrl = zcl_frame_ctrl;
113 req.mfg_code = mfg_code;
115 req.payload_len = payload_len;
116 g_variant_get(payload, "a(y)", &iter);
117 while (g_variant_iter_loop(iter, "(y)", req.payload[i])) {
119 if (i >= ZIGBEE_CUSTOM_SEND_PAYLOAD_LEN)
123 /* Allocate response callback data */
125 zigbee_service_dbus_interface_create_resp_cb_data(custom_object,
126 invocation, NULL, 0);
127 if (NULL == resp_cb_data) {
128 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
130 /* Send failure response */
131 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
136 /* Dispatch request */
137 ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
138 ZBLIB_DRIVER_TYPE_CUSTOM,
139 ZBLIB_CUSTOM_OPS_APS_SEND,
141 on_custom_aps_send_resp, resp_cb_data);
143 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
145 /* Free response callback data */
146 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
148 /* Send failure response */
149 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
157 static void on_custom_zcl_send_resp(ZigBeeServiceInterface *service_interface,
158 guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
160 ZigbeeServiceInterfaceRespCbData_t *cb_data =
161 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
163 ZigbeeCustom *custom_object = NULL;
164 GDBusMethodInvocation *invocation = NULL;
166 ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
168 NOT_USED(service_interface);
169 NOT_USED(request_id);
171 if (NULL == resp_data || 0 == resp_data_len) {
172 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
177 custom_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
178 zblib_check_null_free_and_ret("custom_object", custom_object, cb_data);
180 invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
181 zblib_check_null_free_and_ret("invocation", invocation, cb_data);
183 zigbee_custom_complete_zcl_send(custom_object, invocation, payload->result);
188 static gboolean on_custom_zcl_send(ZigbeeCustom *custom_object,
189 GDBusMethodInvocation *invocation,
194 gchar zcl_frame_ctrl,
200 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
201 ZigbeeCustomZclSend_t req;
202 ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
204 GVariantIter *iter = NULL;
209 memset(&req, 0x0, sizeof(ZigbeeCustomZclSend_t));
211 /* Update request structure */
212 req.node_id = node_id;
214 req.dest_ep = dest_ep;
215 req.cluster_id = cluster_id;
216 req.zcl_frame_ctrl = zcl_frame_ctrl;
218 req.payload_len = payload_len;
219 g_variant_get(payload, "a(y)", &iter);
220 while (g_variant_iter_loop(iter, "(y)", req.payload[i])) {
222 if (i >= ZIGBEE_CUSTOM_SEND_PAYLOAD_LEN)
226 /* Allocate response callback data */
228 zigbee_service_dbus_interface_create_resp_cb_data(custom_object,
229 invocation, NULL, 0);
230 if (NULL == resp_cb_data) {
231 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
233 /* Send failure response */
234 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
239 /* Dispatch request */
240 ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
241 ZBLIB_DRIVER_TYPE_CUSTOM,
242 ZBLIB_CUSTOM_OPS_ZCL_SEND,
244 on_custom_zcl_send_resp, resp_cb_data);
246 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
248 /* Free response callback data */
249 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
251 /* Send failure response */
252 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
260 static void on_custom_send_to_local_resp(ZigBeeServiceInterface *service_interface,
261 guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
263 ZigbeeServiceInterfaceRespCbData_t *cb_data =
264 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
266 ZigbeeCustom *custom_object = NULL;
267 GDBusMethodInvocation *invocation = NULL;
269 ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
271 NOT_USED(service_interface);
272 NOT_USED(request_id);
274 if (NULL == resp_data || 0 == resp_data_len) {
275 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
280 custom_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
281 zblib_check_null_free_and_ret("custom_object", custom_object, cb_data);
283 invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
284 zblib_check_null_free_and_ret("invocation", invocation, cb_data);
286 zigbee_custom_complete_send_to_local(custom_object, invocation, payload->result);
291 static gboolean on_custom_send_to_local(ZigbeeCustom *custom_object,
292 GDBusMethodInvocation *invocation,
297 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
298 ZigbeeCustomSendToLocal_t req;
299 ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
301 GVariantIter *iter = NULL;
306 memset(&req, 0x0, sizeof(ZigbeeCustomSendToLocal_t));
308 /* Update request structure */
310 g_variant_get(data, "a(y)", &iter);
311 while (g_variant_iter_loop(iter, "(y)", req.data[i])) {
313 if (i >= ZIGBEE_CUSTOM_SEND_PAYLOAD_LEN)
317 /* Allocate response callback data */
319 zigbee_service_dbus_interface_create_resp_cb_data(custom_object,
320 invocation, NULL, 0);
321 if (NULL == resp_cb_data) {
322 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
324 /* Send failure response */
325 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
330 /* Dispatch request */
331 ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
332 ZBLIB_DRIVER_TYPE_CUSTOM,
333 ZBLIB_CUSTOM_OPS_SEND_TO_LOCAL,
335 on_custom_send_to_local_resp, resp_cb_data);
337 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
339 /* Free response callback data */
340 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
342 /* Send failure response */
343 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
351 void zigbee_service_dbus_interface_custom_notification(ZigBeeServiceInterface *service_interface,
352 guint noti_id, gpointer noti_data, guint noti_data_len, gpointer noti_cb_data)
354 ZigbeeCustom *custom_object;
356 zblib_check_null_ret("service_interface", service_interface);
358 if (NULL == noti_data || 0 == noti_data_len) {
359 Z_LOGE("noti_data=%p or noti_data_len=%d is null", noti_data, noti_data_len);
363 custom_object = _service_interface_ref_zigbee_custom(service_interface);
364 zblib_check_null_ret("custom_object", custom_object);
366 NOT_USED(noti_cb_data);
369 case ZBLIB_CUSTOM_NOTI_APS_SEND: {
371 GVariant* payload = NULL;
372 GVariantBuilder *attr_builder = NULL;
373 ZigbeeCustomApsSendNoti_t *rsp = (ZigbeeCustomApsSendNoti_t*)noti_data;
375 Z_LOGD("'aps_send_rsp' from : [0x%X]", rsp->node_id);
377 Z_LOGD("rsp->node_id=%x", rsp->node_id);
378 Z_LOGD("rsp->src_ep = %x", rsp->src_ep);
379 Z_LOGD("rsp->dest_ep = %x", rsp->dest_ep);
380 Z_LOGD("rsp->cluster_id = %x", rsp->cluster_id);
381 Z_LOGD("rsp->profile_id = %x", rsp->profile_id);
382 Z_LOGD("rsp->cmd_id = %x", rsp->cmd_id);
383 Z_LOGD("rsp->payload_len = %x", rsp->payload_len);
385 attr_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
386 for (i = 0; i < rsp->payload_len; i++) {
387 g_variant_builder_add(attr_builder, "(y)", rsp->payload[i]);
388 Z_LOGD("rsp->payload[%d] = %x", i, rsp->payload[i]);
390 payload = g_variant_builder_end(attr_builder);
391 g_variant_builder_unref(attr_builder);
393 zigbee_custom_emit_aps_send_rsp(custom_object, rsp->node_id, rsp->src_ep,
394 rsp->dest_ep, rsp->cluster_id, rsp->profile_id, rsp->payload_len,
398 case ZBLIB_CUSTOM_NOTI_ZCL_SEND: {
400 GVariant* payload = NULL;
401 GVariantBuilder *attr_builder = NULL;
402 ZigbeeCustomZclSendNoti_t *rsp = (ZigbeeCustomZclSendNoti_t*)noti_data;
404 Z_LOGD("'zcl_send_rsp' from : [0x%X]", rsp->node_id);
406 Z_LOGD("rsp->node_id=%x", rsp->node_id);
407 Z_LOGD("rsp->src_ep = %x", rsp->src_ep);
408 Z_LOGD("rsp->dest_ep = %x", rsp->dest_ep);
409 Z_LOGD("rsp->cluster_id = %x", rsp->cluster_id);
410 Z_LOGD("rsp->profile_id = %x", rsp->profile_id);
411 Z_LOGD("rsp->cmd_id = %x", rsp->cmd_id);
412 Z_LOGD("rsp->payload_len = %x", rsp->payload_len);
414 attr_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
415 for (i = 0; i < rsp->payload_len; i++) {
416 g_variant_builder_add(attr_builder, "(y)", rsp->payload[i]);
417 Z_LOGD("rsp->payload[%d] = %x", i, rsp->payload[i]);
419 payload = g_variant_builder_end(attr_builder);
420 g_variant_builder_unref(attr_builder);
422 zigbee_custom_emit_zcl_send_rsp(custom_object, rsp->node_id, rsp->src_ep,
423 rsp->dest_ep, rsp->cluster_id, rsp->profile_id, rsp->payload_len, payload);
426 case ZBLIB_CUSTOM_NOTI_SEND_TO_LOCAL: {
428 GVariant* data = NULL;
429 GVariantBuilder *attr_builder = NULL;
430 ZigbeeCustomSendToLocalNoti_t *rsp = (ZigbeeCustomSendToLocalNoti_t*)noti_data;
432 Z_LOGD("'send_to_local_rsp' length : [0x%X]", rsp->length);
434 attr_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
435 for (i = 0; i < rsp->length; i++) {
436 g_variant_builder_add(attr_builder, "(y)", rsp->data[i]);
437 Z_LOGD("rsp->data[%d] = %x", i, rsp->data[i]);
439 data = g_variant_builder_end(attr_builder);
440 g_variant_builder_unref(attr_builder);
442 zigbee_custom_emit_send_to_local_rsp(custom_object, rsp->length, data);
444 if (data) g_variant_unref(data);
448 Z_LOGE("Unexpected notification [%x]", noti_id);
452 /* ZigbeeCustom should be dereferenced */
453 g_object_unref(custom_object);
457 gboolean zigbee_service_dbus_interface_custom_init(ZigBeeServiceInterface *service_interface,
458 ZigbeeObjectSkeleton *zigbee_object)
460 ZigbeeCustom *custom_object;
462 if (NULL == service_interface) {
463 /* LCOV_EXCL_START */
464 Z_LOGE("service_interface is NULL");
469 custom_object = zigbee_custom_skeleton_new();
470 zigbee_object_skeleton_set_custom(zigbee_object, custom_object);
471 g_object_unref(custom_object);
473 Z_LOGI("custom_object: [%p]", custom_object);
476 * Register signal handlers for 'custom' interface
478 g_signal_connect(custom_object,
480 G_CALLBACK(on_custom_aps_send), service_interface);
482 g_signal_connect(custom_object,
484 G_CALLBACK(on_custom_zcl_send), service_interface);
486 g_signal_connect(custom_object,
487 "handle-send-to-local",
488 G_CALLBACK(on_custom_send_to_local), service_interface);