2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "net_nfc_debug_internal.h"
19 #include "net_nfc_server_tag.h"
20 #include "net_nfc_util_defines.h"
21 #include "net_nfc_util_internal.h"
22 #include "net_nfc_util_gdbus_internal.h"
23 #include "net_nfc_server_llcp.h"
24 #include "net_nfc_server_util.h"
25 #include "net_nfc_server_process_phdc.h"
26 #include "net_nfc_server_controller.h"
27 #include "net_nfc_server_phdc.h"
31 typedef struct _net_nfc_server_phdc_pdu_t
35 __attribute__ ((packed)) net_nfc_server_phdc_pdu_t;
37 //callback for internal send/receive
38 typedef void (*_net_nfc_server_phdc_operation_cb)(
39 net_nfc_error_e result,
43 static void _net_nfc_server_phdc_agent_connected_cb(net_nfc_error_e result,
44 net_nfc_target_handle_s *handle,
45 net_nfc_llcp_socket_t socket,
49 typedef struct _net_nfc_server_phdc_op_context_t
51 net_nfc_target_handle_s *handle;
52 net_nfc_error_e result;
58 _net_nfc_server_phdc_operation_cb cb;
60 }net_nfc_server_phdc_op_context_t;
63 typedef struct _net_nfc_server_phdc_job_t
65 net_nfc_server_phdc_context_t *context;
66 net_nfc_target_handle_s *handle;
67 net_nfc_error_e result;
68 net_nfc_llcp_socket_t socket;
71 net_nfc_server_phdc_send_cb cb;
73 }net_nfc_server_phdc_job_t;
75 static void _net_nfc_server_phdc_agent_process(
76 net_nfc_server_phdc_job_t *job);
78 static void _net_nfc_server_phdc_destory_context(
79 net_nfc_server_phdc_op_context_t *context);
81 static void _net_nfc_server_phdc_clear_queue(
85 static void _net_nfc_server_phdc_socket_error_cb(net_nfc_error_e result,
86 net_nfc_target_handle_s *handle,
87 net_nfc_llcp_socket_t socket,
91 static void _net_nfc_server_phdc_recv_cb(
92 net_nfc_llcp_socket_t socket,
93 net_nfc_error_e result,
98 static void _net_nfc_server_phdc_recv(
99 net_nfc_server_phdc_op_context_t *context);
101 static net_nfc_server_phdc_op_context_t* _net_nfc_server_phdc_create_recv_context(
102 net_nfc_target_handle_s *handle,
103 net_nfc_llcp_socket_t socket,
107 static void _net_nfc_server_phdc_manager_op_cb(
108 net_nfc_error_e result,
113 static net_nfc_error_e net_nfc_server_phdc_recv(
114 net_nfc_target_handle_s *handle,
115 net_nfc_llcp_socket_t socket,
116 _net_nfc_server_phdc_operation_cb cb,
119 static void _net_nfc_server_phdc_manager_process(
120 net_nfc_server_phdc_context_t *context);
122 static void _net_nfc_server_phdc_incoming_cb(net_nfc_error_e result,
123 net_nfc_target_handle_s *handle,
124 net_nfc_llcp_socket_t socket,
129 static void _net_nfc_server_phdc_destory_context(net_nfc_server_phdc_op_context_t *context)
133 if (context->data.buffer != NULL)
134 net_nfc_util_free_data(&context->data);
136 _net_nfc_util_free_mem(context);
140 static void _net_nfc_server_phdc_clear_queue(gpointer data,gpointer user_data)
142 net_nfc_server_phdc_job_t *job = (net_nfc_server_phdc_job_t *)data;
148 job->cb((net_nfc_phdc_handle_h)job->context,NET_NFC_OPERATION_FAIL,
149 NET_NFC_PHDC_OPERATION_FAILED, job->user_param);
152 if (job->data.buffer != NULL)
153 net_nfc_util_free_data(&job->data);
155 _net_nfc_util_free_mem(job);
159 static void _net_nfc_server_phdc_socket_error_cb(net_nfc_error_e result,
160 net_nfc_target_handle_s *handle, net_nfc_llcp_socket_t socket, data_s *data,
163 net_nfc_server_phdc_context_t *context = (net_nfc_server_phdc_context_t *)user_param;
165 NFC_DBG("_net_nfc_server_phdc_socket_error_cb socket [%x], result [%d]",
168 RET_IF(NULL == context);
170 if (context->data.buffer != NULL)
171 net_nfc_util_free_data(&context->data);
173 g_queue_foreach(&context->queue, _net_nfc_server_phdc_clear_queue, NULL);
175 _net_nfc_util_free_mem(context);
179 static void _net_nfc_server_phdc_recv_cb(net_nfc_llcp_socket_t socket,
180 net_nfc_error_e result, data_s *data, void *extra, void *user_param)
182 net_nfc_server_phdc_op_context_t *context =
183 (net_nfc_server_phdc_op_context_t *)user_param;
185 uint8_t *buffer = NULL;
186 uint16_t pdu_length = 0;
188 NFC_DBG("_net_nfc_server_phdc_recv_cb, socket[%x], result[%d]", socket, result);
190 RET_IF(NULL == context);
192 context->result = result;
194 if (result != NET_NFC_OK)
196 NFC_ERR("error [%d]", result);
197 context->state = NET_NFC_STATE_ERROR;
201 if (NULL == data || NULL == data->buffer || 0 == data->length)
203 NFC_ERR("invalid response");
204 context->state = NET_NFC_STATE_ERROR;
208 //first 2 bytes is phdc header length
209 memcpy(&pdu_length,data->buffer,PHDC_HEADER_LEN);
211 pdu_length = ntohs(pdu_length);
212 NFC_INFO("pdu_legth [%d]", pdu_length);
217 net_nfc_util_alloc_data(&context->data,pdu_length);
218 if (NULL == context->data.buffer)
220 NFC_ERR("net_nfc_util_alloc_data failed");
221 context->result = NET_NFC_ALLOC_FAIL;
224 buffer =data->buffer;
225 context->data.length = data->length - PHDC_HEADER_LEN;
228 if(context->data.length > 0)
230 memcpy(context->data.buffer ,buffer, context->data.length);
231 NFC_DBG("receive progress... [%d", context->data.length);
235 context->cb(context->result, &context->data, context->user_param);
239 static void _net_nfc_server_phdc_recv(net_nfc_server_phdc_op_context_t *context)
241 RET_IF(NULL == context);
244 net_nfc_error_e result;
246 NFC_DBG("socket [%x] waiting data.....", context->socket);
248 ret = net_nfc_controller_llcp_recv(context->handle, context->socket, context->miu,
249 &result, _net_nfc_server_phdc_recv_cb, context);
253 NFC_ERR("net_nfc_controller_llcp_recv failed, [%d]", result);
255 context->result = result;
256 context->cb(context->result, &context->data, context->user_param);
258 _net_nfc_server_phdc_destory_context(context);
264 static net_nfc_server_phdc_op_context_t* _net_nfc_server_phdc_create_recv_context(
265 net_nfc_target_handle_s *handle, net_nfc_llcp_socket_t socket, void *cb,
270 net_nfc_error_e result;
271 net_nfc_server_phdc_op_context_t *context = NULL;
272 net_nfc_llcp_config_info_s config;
274 ret = net_nfc_controller_llcp_get_remote_config(handle, &config, &result);
278 NFC_ERR("net_nfc_controller_llcp_get_remote_config failed, [%d]", result);
282 _net_nfc_util_alloc_mem(context, sizeof(*context));
284 RETV_IF(NULL == context, NULL);
286 context->handle = handle;
287 context->state = NET_NFC_LLCP_STEP_01;
288 context->socket = socket;
290 context->user_param = user_param;
291 context->miu = MIN(config.miu, net_nfc_server_llcp_get_miu());
297 static net_nfc_error_e net_nfc_server_phdc_recv(net_nfc_target_handle_s *handle,
298 net_nfc_llcp_socket_t socket, _net_nfc_server_phdc_operation_cb cb,
301 net_nfc_error_e result;
302 net_nfc_server_phdc_op_context_t *context = NULL;
305 context = _net_nfc_server_phdc_create_recv_context(handle, socket, cb, user_param);
309 _net_nfc_server_phdc_recv(context);
314 result = NET_NFC_ALLOC_FAIL;
317 cb(result, NULL, user_param);
324 static void _net_nfc_server_phdc_agent_connected_cb(net_nfc_error_e result,
325 net_nfc_target_handle_s *handle, net_nfc_llcp_socket_t socket, data_s *data,
328 net_nfc_server_phdc_context_t *context =
329 (net_nfc_server_phdc_context_t *)user_param;
331 RET_IF(NULL == context);
333 context->socket = socket;
335 if (NET_NFC_OK == result)
336 NFC_DBG("socket [%x] connected. send message", socket);
338 NFC_ERR("connect socket failed, [%d]", result);
340 net_nfc_server_phdc_recv(handle, socket,
341 _net_nfc_server_phdc_manager_op_cb,
344 if (context->cb != NULL)
345 context->cb((net_nfc_phdc_handle_h)context, result,
346 NET_NFC_PHDC_TARGET_CONNECTED, NULL);
350 net_nfc_error_e net_nfc_server_phdc_agent_connect(net_nfc_target_handle_s *handle,
351 const char *san, sap_t sap, net_nfc_server_phdc_cb cb, void *user_param)
354 net_nfc_error_e result;
355 net_nfc_server_phdc_context_t *context = NULL;
357 RETV_IF(NULL == handle, NET_NFC_NULL_PARAMETER);
359 ret = net_nfc_server_target_connected(handle);
362 return NET_NFC_NOT_CONNECTED;
364 _net_nfc_util_alloc_mem(context, sizeof(*context));
368 NFC_ERR("_net_nfc_util_alloc_mem failed");
369 result = NET_NFC_ALLOC_FAIL;
373 context->handle = handle;
375 context->user_param = user_param;
377 result = net_nfc_server_llcp_simple_client(handle, san, sap,
378 _net_nfc_server_phdc_agent_connected_cb,
379 _net_nfc_server_phdc_socket_error_cb,
382 if (result != NET_NFC_OK)
384 NFC_ERR("net_nfc_server_llcp_simple_client failed, [%d]", result);
389 NFC_DBG("start phdc agent san [%s]", san);
391 NFC_DBG("start phdc agent, sap [%d]", sap);
398 if (context->data.buffer != NULL)
400 net_nfc_util_free_data(&context->data);
402 _net_nfc_util_free_mem(context);
409 static void _net_nfc_server_phdc_agent_do_job(
410 net_nfc_server_phdc_context_t *context)
412 if (context->state == NET_NFC_LLCP_IDLE && g_queue_is_empty(&context->queue) == false)
414 net_nfc_server_phdc_job_t *job;
416 job = g_queue_pop_head(&context->queue);
419 context->state = NET_NFC_LLCP_STEP_01;
420 job->state = NET_NFC_LLCP_STEP_01;
421 _net_nfc_server_phdc_agent_process(job);
426 static net_nfc_server_phdc_op_context_t* _net_nfc_server_phdc_create_send_context(
427 net_nfc_target_handle_s *handle, net_nfc_llcp_socket_t socket, data_s *data,
428 void *cb, void *user_param)
431 uint32_t data_len = 0;
433 uint8_t *buffer = NULL;
434 net_nfc_server_phdc_op_context_t *context = NULL;
435 net_nfc_llcp_config_info_s config;
436 net_nfc_error_e result;
438 ret = net_nfc_controller_llcp_get_remote_config(handle,
443 NFC_ERR("net_nfc_controller_llcp_get_remote_config failed, [%d]", result);
447 _net_nfc_util_alloc_mem(context, sizeof(*context));
448 RETV_IF(NULL == context, NULL);
451 data_len =data->length;
455 net_nfc_util_alloc_data(&context->data,data_len+PHDC_HEADER_LEN);
456 if (NULL == context->data.buffer)
458 _net_nfc_util_free_mem(context);
462 length = (uint16_t)data->length;
463 length +=PHDC_HEADER_LEN;
464 buffer = context->data.buffer;
466 if(data->buffer != NULL)
468 uint16_t network_length = htons(length);
469 memcpy(buffer,&network_length,PHDC_HEADER_LEN);
470 buffer+=PHDC_HEADER_LEN;
471 memcpy(buffer,data->buffer,data->length);
472 context->data.length = length;
476 context->handle = handle;
477 context->socket = socket;
479 context->user_param = user_param;
480 context->miu = MIN(config.miu, net_nfc_server_llcp_get_miu());
485 static void _net_nfc_server_phdc_send_cb(net_nfc_llcp_socket_t socket,
486 net_nfc_error_e result, data_s *data, void *extra, void *user_param)
488 net_nfc_server_phdc_op_context_t *context =
489 (net_nfc_server_phdc_op_context_t *)user_param;
491 NFC_DBG("_net_nfc_server_phdc_send_cb, socket[%x], result[%d]", socket, result);
493 RET_IF(NULL == context);
495 context->result = result;
497 /* complete and invoke callback */
498 context->cb(context->result, NULL, context->user_param);
500 _net_nfc_server_phdc_destory_context(context);
504 static void _net_nfc_server_phdc_send(net_nfc_server_phdc_op_context_t *context)
508 net_nfc_error_e result;
510 RET_IF(NULL == context);
512 req_msg.length = context->data.length;
513 req_msg.buffer = context->data.buffer;
515 NFC_DBG("try to send data, socket [%x]",context->socket);
517 ret= net_nfc_controller_llcp_send(context->handle, context->socket,
518 &req_msg, &result, _net_nfc_server_phdc_send_cb, context);
522 NFC_ERR("net_nfc_controller_llcp_send failed, [%d]",result);
523 context->result = result;
525 context->cb(context->result, NULL, context->user_param);
526 _net_nfc_server_phdc_destory_context(context);
530 static void _net_nfc_server_phdc_agent_send_cb(net_nfc_error_e result,data_s *data,
533 net_nfc_server_phdc_job_t*job = (net_nfc_server_phdc_job_t *)user_param;
537 job->result = result;
539 if (NET_NFC_OK ==result)
541 job->state = NET_NFC_LLCP_STEP_RETURN;
542 net_nfc_util_free_data(&job->data);
546 NFC_ERR("net_nfc_server_phdc_send failed, [%d]", result);
547 job->state = NET_NFC_STATE_ERROR;
550 _net_nfc_server_phdc_agent_process(job);
554 net_nfc_error_e net_nfc_server_phdc_send(net_nfc_target_handle_s *handle,
555 net_nfc_llcp_socket_t socket, data_s *data, _net_nfc_server_phdc_operation_cb cb,
558 net_nfc_error_e result;
559 net_nfc_server_phdc_op_context_t *context = NULL;
562 context = _net_nfc_server_phdc_create_send_context(handle, socket,data,
568 _net_nfc_server_phdc_send(context);
573 NFC_ERR("_net_nfc_server_phdc_create_send_context failed");
574 result = NET_NFC_ALLOC_FAIL;
577 cb(result, NULL, user_param);
583 static void _net_nfc_server_phdc_agent_process(net_nfc_server_phdc_job_t *job)
591 case NET_NFC_LLCP_STEP_01 :
592 NFC_DBG("NET_NFC_LLCP_STEP_01");
595 net_nfc_server_phdc_send(job->handle, job->socket, &job->data,
596 _net_nfc_server_phdc_agent_send_cb, job);
599 case NET_NFC_LLCP_STEP_RETURN :
600 NFC_DBG("NET_NFC_LLCP_STEP_RETURN");
602 /* complete and invoke callback */
605 job->cb((net_nfc_phdc_handle_h)job->context, NET_NFC_OK,
606 NET_NFC_PHDC_DATA_RECEIVED, job->user_param);
612 case NET_NFC_STATE_ERROR :
614 NFC_ERR("NET_NFC_STATE_ERROR");
616 /* error, invoke callback */
617 NFC_ERR("phdc_agent_send failed, [%d]", job->result);
620 job->cb((net_nfc_phdc_handle_h)job->context, job->result,
621 NET_NFC_PHDC_OPERATION_FAILED, job->user_param);
630 net_nfc_server_phdc_context_t *context = job->context;
632 if (job->data.buffer != NULL)
633 net_nfc_util_free_data(&job->data);
635 _net_nfc_util_free_mem(job);
636 context->state = NET_NFC_LLCP_IDLE;
637 _net_nfc_server_phdc_agent_do_job(context);
642 net_nfc_error_e net_nfc_server_phdc_agent_request(net_nfc_phdc_handle_h handle,
643 data_s *data, net_nfc_server_phdc_send_cb cb, void *user_param)
646 net_nfc_error_e result = NET_NFC_OK;
647 net_nfc_server_phdc_job_t *job = NULL;
648 net_nfc_server_phdc_context_t *context = (net_nfc_server_phdc_context_t *)handle;
650 RETV_IF(NULL == handle, NET_NFC_NULL_PARAMETER);
651 RETV_IF(NULL == data, NET_NFC_NULL_PARAMETER);
652 RETV_IF(NULL == data->buffer, NET_NFC_NULL_PARAMETER);
654 ret =net_nfc_server_target_connected(context->handle);
657 return NET_NFC_NOT_CONNECTED;
660 _net_nfc_util_alloc_mem(job, sizeof(*job));
663 net_nfc_util_alloc_data(&job->data, data->length);
664 if (job->data.buffer != NULL)
665 memcpy(job->data.buffer, data->buffer, data->length);
668 job->user_param = user_param;
669 job->context = context;
670 job->handle = context->handle;
671 job->socket = context->socket;
672 g_queue_push_tail(&context->queue, job);
675 return NET_NFC_ALLOC_FAIL;
677 NFC_INFO("enqueued jobs [%d]", g_queue_get_length(&context->queue));
679 /* if agent is idle, starts sending request */
680 if (context->state == NET_NFC_LLCP_IDLE)
681 _net_nfc_server_phdc_agent_do_job(context);
683 NFC_INFO("agent is working. this job will be enqueued");
689 net_nfc_error_e net_nfc_server_phdc_agent_start(net_nfc_target_handle_s *handle,
690 const char *san, sap_t sap, net_nfc_server_phdc_cb cb, void *user_param)
692 net_nfc_error_e result;
694 RETV_IF(NULL == handle, NET_NFC_NULL_PARAMETER);
695 RETV_IF(NULL == san, NET_NFC_NULL_PARAMETER);
697 /* start PHDC Agent, register your callback */
698 result = net_nfc_server_phdc_agent_connect(handle, san, sap,
701 if (result != NET_NFC_OK)
703 NFC_ERR("net_nfc_server_phdc_agent_connect failed, [%d]",result);
708 static void _net_nfc_server_phdc_manager_op_cb( net_nfc_error_e result, data_s *data,
711 net_nfc_server_phdc_context_t *context =
712 (net_nfc_server_phdc_context_t *)user_param;
714 NFC_DBG("_net_nfc_server_phdc_manager_op_cb result [%d]", result);
716 RET_IF(NULL == context);
718 context->result = result;
719 if (NET_NFC_OK == result && data != NULL && data->buffer != NULL)
721 NFC_DBG("received message, length [%d]", data->length);
723 net_nfc_util_alloc_data(&context->data, data->length);
724 if (context->data.buffer != NULL)
726 memcpy(context->data.buffer,data->buffer, data->length);
727 context->state = NET_NFC_LLCP_STEP_02;
731 NFC_ERR("net_nfc_util_alloc_data failed");
732 context->state = NET_NFC_STATE_ERROR;
733 context->result = NET_NFC_ALLOC_FAIL;
738 NFC_ERR("net_nfc_server_phdc_recv failed, [%d]", result);
739 context->state = NET_NFC_STATE_ERROR;
742 _net_nfc_server_phdc_manager_process(context);
747 static void _net_nfc_server_phdc_manager_process(
748 net_nfc_server_phdc_context_t *context)
751 RET_IF(NULL == context);
753 switch (context->state)
755 case NET_NFC_LLCP_STEP_01 :
756 NFC_INFO("NET_NFC_LLCP_STEP_01 ");
757 /*receive the Agent data*/
758 net_nfc_server_phdc_recv( context->handle,context->socket,
759 _net_nfc_server_phdc_manager_op_cb, context);
761 case NET_NFC_LLCP_STEP_02 :
762 NFC_INFO("NET_NFC_LLCP_STEP_02");
763 if (context->cb != NULL)
765 /* complete operation and invoke the callback*/
766 context->cb((net_nfc_phdc_handle_h)context,NET_NFC_OK,
767 NET_NFC_PHDC_DATA_RECEIVED, &context->data);
771 case NET_NFC_STATE_ERROR :
772 NFC_INFO("NET_NFC_STATE_ERROR");
774 if (context->cb != NULL)
776 context->cb((net_nfc_phdc_handle_h)context,context->result,
777 NET_NFC_PHDC_OPERATION_FAILED,&context->data);
785 context->state = NET_NFC_LLCP_IDLE;
787 net_nfc_server_phdc_recv(context->handle,
789 _net_nfc_server_phdc_manager_op_cb,
796 static void _net_nfc_server_phdc_incoming_cb(net_nfc_error_e result,
797 net_nfc_target_handle_s *handle, net_nfc_llcp_socket_t socket, data_s *data,
800 net_nfc_server_phdc_context_t *context =
801 (net_nfc_server_phdc_context_t *)user_param;
803 net_nfc_server_phdc_context_t *accept_context = NULL;
805 RET_IF(NULL == context);
807 NFC_DBG("phdc incoming socket [%x], result [%d]", socket, result);
809 if (result != NET_NFC_OK)
811 NFC_ERR("listen socket failed, [%d]", result);
815 _net_nfc_util_alloc_mem(accept_context, sizeof(*accept_context));
817 if (NULL == accept_context)
819 NFC_ERR("_net_nfc_util_alloc_mem failed");
820 result = NET_NFC_ALLOC_FAIL;
824 accept_context->handle = context->handle;
825 accept_context->socket = socket;
826 accept_context->cb = context->cb;
827 accept_context->user_param = context->user_param;
828 accept_context->state = NET_NFC_LLCP_STEP_01;
830 result = net_nfc_server_llcp_simple_accept(handle, socket,
831 _net_nfc_server_phdc_socket_error_cb, accept_context);
833 if (result != NET_NFC_OK)
835 NFC_ERR("net_nfc_server_llcp_simple_accept failed, [%d]",result);
839 NFC_DBG("socket [%x] accepted.. waiting for request message", socket);
841 accept_context->cb((net_nfc_phdc_handle_h)accept_context, result,
842 NET_NFC_PHDC_TARGET_CONNECTED, data);
844 _net_nfc_server_phdc_manager_process(accept_context);
848 if (accept_context != NULL)
850 _net_nfc_util_free_mem(accept_context);
854 net_nfc_error_e net_nfc_server_phdc_manager_start(net_nfc_target_handle_s *handle,
855 const char *san, sap_t sap, net_nfc_server_phdc_cb cb, void *user_param)
858 net_nfc_error_e result;
859 net_nfc_server_phdc_context_t *context = NULL;
861 RETV_IF(NULL == handle, NET_NFC_NULL_PARAMETER);
862 RETV_IF(NULL == san, NET_NFC_NULL_PARAMETER);
864 ret = net_nfc_server_target_connected(handle);
867 return NET_NFC_NOT_CONNECTED;
869 _net_nfc_util_alloc_mem(context, sizeof(*context));
872 NFC_ERR("_create_phdc_context failed");
873 result = NET_NFC_ALLOC_FAIL;
877 context->handle = handle;
879 context->user_param = user_param;
880 context->state = NET_NFC_LLCP_STEP_01;
882 if(!strcmp(san,PHDC_SAN))
884 /*Handle the default PHDC SAN*/
885 result = net_nfc_server_llcp_simple_server(handle, san,sap,
886 _net_nfc_server_phdc_incoming_cb,_net_nfc_server_phdc_socket_error_cb,
891 /*Handle other SAN, Implement as and when needed.*/
892 result = NET_NFC_NOT_SUPPORTED;
895 if (result != NET_NFC_OK)
897 NFC_ERR("net_nfc_server_llcp_simple_server failed, [%d]",result);
901 NFC_DBG("start phdc manager, san [%s], sap [%d]", san, sap);
906 _net_nfc_util_free_mem(context);
911 ///////////////////////////////////////////////////////////////////