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>
23 static void *_service_interface_ref_zigbee_custom(
24 ZigBeeServiceInterface *service_interface)
26 ZigbeeObjectSkeleton *zigbee_object = NULL;
27 ZigbeeCustomData_t *custom_data = NULL;
28 ZigbeeCustom *custom_object = NULL;
30 custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
31 if (NULL == custom_data) {
32 Z_LOGE("D-BUS service interface custom_data is NULL!");
36 /* Get zigbee object */
37 zigbee_object = g_hash_table_lookup(custom_data->objects, ZIGBEE_SERVICE_PATH);
38 if (NULL == zigbee_object) {
39 Z_LOGW("Cannot find ZigBee D-BUS interface object!", zigbee_object);
43 custom_object = zigbee_object_get_custom(ZIGBEE_OBJECT(zigbee_object));
47 static void on_custom_aps_send_resp(ZigBeeServiceInterface *service_interface,
48 guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
50 ZigbeeServiceInterfaceRespCbData_t *cb_data =
51 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
53 ZigbeeCustom *custom_object = NULL;
54 GDBusMethodInvocation *invocation = NULL;
56 ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
58 NOT_USED(service_interface);
61 if (NULL == resp_data || 0 == resp_data_len) {
62 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
67 custom_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
68 zblib_check_null_free_and_ret("custom_object", custom_object, cb_data);
70 invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
71 zblib_check_null_free_and_ret("invocation", invocation, cb_data);
73 zigbee_custom_complete_aps_send(custom_object, invocation, payload->result);
78 static gboolean on_custom_aps_send(ZigbeeCustom *custom_object,
79 GDBusMethodInvocation *invocation,
93 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
94 ZigbeeCustomApsSend_t req;
95 ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
97 GVariantIter *iter = NULL;
102 memset(&req, 0x0, sizeof(ZigbeeCustomApsSend_t));
104 /* Update request structure */
105 req.node_id = node_id;
106 req.aps_frame_ctrl = aps_frame_ctrl;
108 req.dest_ep = dest_ep;
109 req.cluster_id = cluster_id;
110 req.profile_id = profile_id;
111 req.zcl_frame_ctrl = zcl_frame_ctrl;
112 req.mfg_code = mfg_code;
114 req.payload_len = payload_len;
115 g_variant_get(payload, "a(y)", &iter);
116 while (g_variant_iter_loop(iter, "(y)", req.payload[i])) {
118 if (i >= ZIGBEE_CUSTOM_SEND_PAYLOAD_LEN)
122 /* Allocate response callback data */
124 zigbee_service_dbus_interface_create_resp_cb_data(custom_object,
125 invocation, NULL, 0);
126 if (NULL == resp_cb_data) {
127 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
129 /* Send failure response */
130 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
135 /* Dispatch request */
136 ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
137 ZBLIB_DRIVER_TYPE_CUSTOM,
138 ZBLIB_CUSTOM_OPS_APS_SEND,
140 on_custom_aps_send_resp, resp_cb_data);
142 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
144 /* Free response callback data */
145 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
147 /* Send failure response */
148 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
156 static void on_custom_zcl_send_resp(ZigBeeServiceInterface *service_interface,
157 guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
159 ZigbeeServiceInterfaceRespCbData_t *cb_data =
160 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
162 ZigbeeCustom *custom_object = NULL;
163 GDBusMethodInvocation *invocation = NULL;
165 ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
167 NOT_USED(service_interface);
168 NOT_USED(request_id);
170 if (NULL == resp_data || 0 == resp_data_len) {
171 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
176 custom_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
177 zblib_check_null_free_and_ret("custom_object", custom_object, cb_data);
179 invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
180 zblib_check_null_free_and_ret("invocation", invocation, cb_data);
182 zigbee_custom_complete_zcl_send(custom_object, invocation, payload->result);
187 static gboolean on_custom_zcl_send(ZigbeeCustom *custom_object,
188 GDBusMethodInvocation *invocation,
193 gchar zcl_frame_ctrl,
199 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
200 ZigbeeCustomZclSend_t req;
201 ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
203 GVariantIter *iter = NULL;
208 memset(&req, 0x0, sizeof(ZigbeeCustomZclSend_t));
210 /* Update request structure */
211 req.node_id = node_id;
213 req.dest_ep = dest_ep;
214 req.cluster_id = cluster_id;
215 req.zcl_frame_ctrl = zcl_frame_ctrl;
217 req.payload_len = payload_len;
218 g_variant_get(payload, "a(y)", &iter);
219 while (g_variant_iter_loop(iter, "(y)", req.payload[i])) {
221 if (i >= ZIGBEE_CUSTOM_SEND_PAYLOAD_LEN)
225 /* Allocate response callback data */
227 zigbee_service_dbus_interface_create_resp_cb_data(custom_object,
228 invocation, NULL, 0);
229 if (NULL == resp_cb_data) {
230 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
232 /* Send failure response */
233 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
238 /* Dispatch request */
239 ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
240 ZBLIB_DRIVER_TYPE_CUSTOM,
241 ZBLIB_CUSTOM_OPS_ZCL_SEND,
243 on_custom_zcl_send_resp, resp_cb_data);
245 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
247 /* Free response callback data */
248 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
250 /* Send failure response */
251 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
259 static void on_custom_send_to_local_resp(ZigBeeServiceInterface *service_interface,
260 guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
262 ZigbeeServiceInterfaceRespCbData_t *cb_data =
263 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
265 ZigbeeCustom *custom_object = NULL;
266 GDBusMethodInvocation *invocation = NULL;
268 ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
270 NOT_USED(service_interface);
271 NOT_USED(request_id);
273 if (NULL == resp_data || 0 == resp_data_len) {
274 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
279 custom_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
280 zblib_check_null_free_and_ret("custom_object", custom_object, cb_data);
282 invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
283 zblib_check_null_free_and_ret("invocation", invocation, cb_data);
285 zigbee_custom_complete_send_to_local(custom_object, invocation, payload->result);
290 static gboolean on_custom_send_to_local(ZigbeeCustom *custom_object,
291 GDBusMethodInvocation *invocation,
296 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
297 ZigbeeCustomSendToLocal_t req;
298 ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
300 GVariantIter *iter = NULL;
305 memset(&req, 0x0, sizeof(ZigbeeCustomSendToLocal_t));
307 /* Update request structure */
309 g_variant_get(data, "a(y)", &iter);
310 while (g_variant_iter_loop(iter, "(y)", req.data[i])) {
312 if (i >= ZIGBEE_CUSTOM_SEND_PAYLOAD_LEN)
316 /* Allocate response callback data */
318 zigbee_service_dbus_interface_create_resp_cb_data(custom_object,
319 invocation, NULL, 0);
320 if (NULL == resp_cb_data) {
321 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
323 /* Send failure response */
324 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
329 /* Dispatch request */
330 ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
331 ZBLIB_DRIVER_TYPE_CUSTOM,
332 ZBLIB_CUSTOM_OPS_SEND_TO_LOCAL,
334 on_custom_send_to_local_resp, resp_cb_data);
336 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
338 /* Free response callback data */
339 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
341 /* Send failure response */
342 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
350 void zigbee_service_dbus_interface_custom_notification(ZigBeeServiceInterface *service_interface,
351 guint noti_id, gpointer noti_data, guint noti_data_len, gpointer noti_cb_data)
353 ZigbeeCustom *custom_object;
355 zblib_check_null_ret("service_interface", service_interface);
357 if (NULL == noti_data || 0 == noti_data_len) {
358 Z_LOGE("noti_data=%p or noti_data_len=%d is null", noti_data, noti_data_len);
362 custom_object = _service_interface_ref_zigbee_custom(service_interface);
363 zblib_check_null_ret("custom_object", custom_object);
365 NOT_USED(noti_cb_data);
368 case ZBLIB_CUSTOM_NOTI_APS_SEND: {
370 GVariant* payload = NULL;
371 GVariantBuilder *attr_builder = NULL;
372 ZigbeeCustomApsSendNoti_t *rsp = (ZigbeeCustomApsSendNoti_t*)noti_data;
374 Z_LOGD("'aps_send_rsp' from : [0x%X]", rsp->node_id);
376 Z_LOGD("rsp->node_id=%x", rsp->node_id);
377 Z_LOGD("rsp->src_ep = %x", rsp->src_ep);
378 Z_LOGD("rsp->dest_ep = %x", rsp->dest_ep);
379 Z_LOGD("rsp->cluster_id = %x", rsp->cluster_id);
380 Z_LOGD("rsp->profile_id = %x", rsp->profile_id);
381 Z_LOGD("rsp->cmd_id = %x", rsp->cmd_id);
382 Z_LOGD("rsp->payload_len = %x", rsp->payload_len);
384 attr_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
385 for (i = 0; i < rsp->payload_len; i++) {
386 g_variant_builder_add(attr_builder, "(y)", rsp->payload[i]);
387 Z_LOGD("rsp->payload[%d] = %x", i, rsp->payload[i]);
389 payload = g_variant_builder_end(attr_builder);
390 g_variant_builder_unref(attr_builder);
392 zigbee_custom_emit_aps_send_rsp(custom_object, rsp->node_id, rsp->src_ep,
393 rsp->dest_ep, rsp->cluster_id, rsp->profile_id, rsp->payload_len,
397 case ZBLIB_CUSTOM_NOTI_ZCL_SEND: {
399 GVariant* payload = NULL;
400 GVariantBuilder *attr_builder = NULL;
401 ZigbeeCustomZclSendNoti_t *rsp = (ZigbeeCustomZclSendNoti_t*)noti_data;
403 Z_LOGD("'zcl_send_rsp' from : [0x%X]", rsp->node_id);
405 Z_LOGD("rsp->node_id=%x", rsp->node_id);
406 Z_LOGD("rsp->src_ep = %x", rsp->src_ep);
407 Z_LOGD("rsp->dest_ep = %x", rsp->dest_ep);
408 Z_LOGD("rsp->cluster_id = %x", rsp->cluster_id);
409 Z_LOGD("rsp->profile_id = %x", rsp->profile_id);
410 Z_LOGD("rsp->cmd_id = %x", rsp->cmd_id);
411 Z_LOGD("rsp->payload_len = %x", rsp->payload_len);
413 attr_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
414 for (i = 0; i < rsp->payload_len; i++) {
415 g_variant_builder_add(attr_builder, "(y)", rsp->payload[i]);
416 Z_LOGD("rsp->payload[%d] = %x", i, rsp->payload[i]);
418 payload = g_variant_builder_end(attr_builder);
419 g_variant_builder_unref(attr_builder);
421 zigbee_custom_emit_zcl_send_rsp(custom_object, rsp->node_id, rsp->src_ep,
422 rsp->dest_ep, rsp->cluster_id, rsp->profile_id, rsp->payload_len, payload);
425 case ZBLIB_CUSTOM_NOTI_SEND_TO_LOCAL: {
427 GVariant* data = NULL;
428 GVariantBuilder *attr_builder = NULL;
429 ZigbeeCustomSendToLocalNoti_t *rsp = (ZigbeeCustomSendToLocalNoti_t*)noti_data;
431 Z_LOGD("'send_to_local_rsp' length : [0x%X]", rsp->length);
433 attr_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
434 for (i = 0; i < rsp->length; i++) {
435 g_variant_builder_add(attr_builder, "(y)", rsp->data[i]);
436 Z_LOGD("rsp->data[%d] = %x", i, rsp->data[i]);
438 data = g_variant_builder_end(attr_builder);
439 g_variant_builder_unref(attr_builder);
441 zigbee_custom_emit_send_to_local_rsp(custom_object, rsp->length, data);
443 if (data) g_variant_unref(data);
447 Z_LOGE("Unexpected notification [%x]", noti_id);
451 /* ZigbeeCustom should be dereferenced */
452 g_object_unref(custom_object);
455 gboolean zigbee_service_dbus_interface_custom_init(ZigBeeServiceInterface *service_interface,
456 ZigbeeObjectSkeleton *zigbee_object)
458 ZigbeeCustom *custom_object;
460 if (NULL == service_interface) {
461 Z_LOGE("service_interface is NULL");
465 custom_object = zigbee_custom_skeleton_new();
466 zigbee_object_skeleton_set_custom(zigbee_object, custom_object);
467 g_object_unref(custom_object);
469 Z_LOGI("custom_object: [%p]", custom_object);
472 * Register signal handlers for 'custom' interface
474 g_signal_connect(custom_object,
476 G_CALLBACK(on_custom_aps_send), service_interface);
478 g_signal_connect(custom_object,
480 G_CALLBACK(on_custom_zcl_send), service_interface);
482 g_signal_connect(custom_object,
483 "handle-send-to-local",
484 G_CALLBACK(on_custom_send_to_local), service_interface);