/******************************************************************************* ** ** Function nfa_ce_api_deregister_listen ** ** Description Internal function called by listening for Felica system ** code, ISO-DEP AID, or UICC technology ** ** Returns: ** NFA_STATUS_OK, if command accepted ** NFA_STATUS_BAD_HANDLE invalid handle ** NFA_STATUS_FAILED: otherwise ** *******************************************************************************/ tNFA_STATUS nfa_ce_api_deregister_listen (tNFA_HANDLE handle, UINT32 listen_info) { tNFA_CE_MSG *p_ce_msg; /* Validate handle */ if ( (listen_info != NFA_CE_LISTEN_INFO_UICC #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) && listen_info != NFA_CE_LISTEN_INFO_ESE #endif ) &&((handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_CE) ) { NFA_TRACE_ERROR0 ("nfa_ce_api_reregister_listen: Invalid handle"); return (NFA_STATUS_BAD_HANDLE); } if ((p_ce_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) (sizeof (tNFA_CE_MSG)))) != NULL) { p_ce_msg->hdr.event = NFA_CE_API_DEREG_LISTEN_EVT; p_ce_msg->dereg_listen.handle = handle; p_ce_msg->dereg_listen.listen_info = listen_info; nfa_sys_sendmsg (p_ce_msg); return (NFA_STATUS_OK); } else { NFA_TRACE_ERROR0 ("nfa_ce_api_reregister_listen: Out of buffers"); return (NFA_STATUS_FAILED); } }
/******************************************************************************* ** ** Function NFA_CeConfigureLocalTag ** ** Description Configure local NDEF tag. ** ** Tag events will be notifed using the tNFA_CONN_CBACK ** (registered during NFA_Enable) ** ** The NFA_CE_LOCAL_TAG_CONFIGURED_EVT reports the status of the ** operation. ** ** Activation and deactivation are reported using the ** NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events ** ** If a write-request is received to update the tag memory, ** an NFA_CE_NDEF_WRITE_CPLT_EVT will notify the application, along ** with a buffer containing the updated contents. ** ** To disable the local NDEF tag, set protocol_mask=0 ** ** The NDEF data provided by p_ndef_data must be persistent ** as long as the local NDEF tag is enabled. ** ** ** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT ** should happen before calling this function. Also, Input parameters p_uid and ** uid_len are reserved for future use. ** ** Returns: ** NFA_STATUS_OK, if command accepted ** NFA_STATUS_INVALID_PARAM, ** if protocol_maks is not 0 and p_ndef_data is NULL ** (or)uid_len is not 0 ** (or)if protocol mask is set for Type 1 or Type 2 ** ** NFA_STATUS_FAILED: otherwise ** *******************************************************************************/ tNFA_STATUS NFA_CeConfigureLocalTag (tNFA_PROTOCOL_MASK protocol_mask, UINT8 *p_ndef_data, UINT16 ndef_cur_size, UINT16 ndef_max_size, BOOLEAN read_only, UINT8 uid_len, UINT8 *p_uid) { tNFA_CE_MSG *p_msg; NFA_TRACE_API0 ("NFA_CeConfigureLocalTag ()"); if (protocol_mask) { /* If any protocols are specified, then NDEF buffer pointer must be non-NULL */ if (p_ndef_data == NULL) { NFA_TRACE_ERROR0 ("NFA_CeConfigureLocalTag: NULL ndef data pointer"); return (NFA_STATUS_INVALID_PARAM); } if ((protocol_mask & NFA_PROTOCOL_MASK_T1T) || (protocol_mask & NFA_PROTOCOL_MASK_T2T)) { NFA_TRACE_ERROR0 ("NFA_CeConfigureLocalTag: Cannot emulate Type 1 / Type 2 tag"); return (NFA_STATUS_INVALID_PARAM); } if (uid_len) { NFA_TRACE_ERROR1 ("NFA_CeConfigureLocalTag: Cannot Set UID for Protocol_mask: 0x%x", protocol_mask); return (NFA_STATUS_INVALID_PARAM); } } if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL) { p_msg->local_tag.hdr.event = NFA_CE_API_CFG_LOCAL_TAG_EVT; /* Copy ndef info */ p_msg->local_tag.protocol_mask = protocol_mask; p_msg->local_tag.p_ndef_data = p_ndef_data; p_msg->local_tag.ndef_cur_size = ndef_cur_size; p_msg->local_tag.ndef_max_size = ndef_max_size; p_msg->local_tag.read_only = read_only; p_msg->local_tag.uid_len = uid_len; if (uid_len) memcpy (p_msg->local_tag.uid, p_uid, uid_len); nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_RegisterNDefTypeHandler ** ** Description This function allows the applications to register for ** specific types of NDEF records. When NDEF records are ** received, NFA will parse the record-type field, and pass ** the record to the registered tNFA_NDEF_CBACK. ** ** For records types which were not registered, the record will ** be sent to the default handler. A default type-handler may ** be registered by calling this NFA_RegisterNDefTypeHandler ** with tnf=NFA_TNF_DEFAULT. In this case, all un-registered ** record types will be sent to the callback. Only one default ** handler may be registered at a time. ** ** An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK ** to indicate that registration was successful, and provide a ** handle for this record type. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_RegisterNDefTypeHandler (BOOLEAN handle_whole_message, tNFA_TNF tnf, UINT8 *p_type_name, UINT8 type_name_len, tNFA_NDEF_CBACK *p_ndef_cback) { tNFA_DM_API_REG_NDEF_HDLR *p_msg; NFA_TRACE_API2 ("NFA_RegisterNDefTypeHandler (): handle whole ndef message: %i, tnf=0x%02x", handle_whole_message, tnf); /* Check for NULL callback */ if (!p_ndef_cback) { NFA_TRACE_ERROR0 ("NFA_RegisterNDefTypeHandler (): error - null callback"); return (NFA_STATUS_INVALID_PARAM); } if ((p_msg = (tNFA_DM_API_REG_NDEF_HDLR *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_REG_NDEF_HDLR) + type_name_len))) != NULL) { p_msg->hdr.event = NFA_DM_API_REG_NDEF_HDLR_EVT; p_msg->flags = (handle_whole_message ? NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE : 0); p_msg->tnf = tnf; p_msg->name_len = type_name_len; p_msg->p_ndef_cback = p_ndef_cback; memcpy (p_msg->name, p_type_name, type_name_len); nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_Select ** ** Description Select one from detected devices during discovery ** (from NFA_DISC_RESULT_EVTs). The application should wait for ** the final NFA_DISC_RESULT_EVT before selecting. ** ** An NFA_SELECT_RESULT_EVT indicates whether selection was successful or not. ** If failed then application must select again or deactivate by NFA_Deactivate(). ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_INVALID_PARAM if RF interface is not matched protocol ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_Select (UINT8 rf_disc_id, tNFA_NFC_PROTOCOL protocol, tNFA_INTF_TYPE rf_interface) { tNFA_DM_API_SELECT *p_msg; NFA_TRACE_API3 ("NFA_Select (): rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X", rf_disc_id, protocol, rf_interface); if ( ((rf_interface == NFA_INTERFACE_ISO_DEP) && (protocol != NFA_PROTOCOL_ISO_DEP)) ||((rf_interface == NFA_INTERFACE_NFC_DEP) && (protocol != NFA_PROTOCOL_NFC_DEP)) ) { NFA_TRACE_ERROR0 ("NFA_Select (): RF interface is not matched protocol"); return (NFA_STATUS_INVALID_PARAM); } if ((p_msg = (tNFA_DM_API_SELECT *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_SELECT)))) != NULL) { p_msg->hdr.event = NFA_DM_API_SELECT_EVT; p_msg->rf_disc_id = rf_disc_id; p_msg->protocol = protocol; p_msg->rf_interface = rf_interface; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_RequestExclusiveRfControl ** ** Description Request exclusive control of NFC. ** - Previous behavior (polling/tag reading, DH card emulation) ** will be suspended . ** - Polling and listening will be done based on the specified ** params ** ** The NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT event of ** tNFA_CONN_CBACK indicates the status of the operation. ** ** NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT indicates link ** activation/deactivation. ** ** NFA_SendRawFrame is used to send data to the peer. NFA_DATA_EVT ** indicates data from the peer. ** ** If a tag is activated, then the NFA_RW APIs may be used to ** send commands to the tag. Incoming NDEF messages are sent to ** the NDEF callback. ** ** Once exclusive RF control has started, NFA will not activate ** LLCP internally. The application has exclusive control of ** the link. ** ** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT ** should happen before calling this function ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_RequestExclusiveRfControl (tNFA_TECHNOLOGY_MASK poll_mask, tNFA_LISTEN_CFG *p_listen_cfg, tNFA_CONN_CBACK *p_conn_cback, tNFA_NDEF_CBACK *p_ndef_cback) { tNFA_DM_API_REQ_EXCL_RF_CTRL *p_msg; NFA_TRACE_API1 ("NFA_RequestExclusiveRfControl () poll_mask=0x%x", poll_mask); if (!p_conn_cback) { NFA_TRACE_ERROR0 ("NFA_RequestExclusiveRfControl (): error null callback"); return (NFA_STATUS_FAILED); } if ((p_msg = (tNFA_DM_API_REQ_EXCL_RF_CTRL *) GKI_getbuf (sizeof (tNFA_DM_API_REQ_EXCL_RF_CTRL))) != NULL) { p_msg->hdr.event = NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT; p_msg->poll_mask = poll_mask; p_msg->p_conn_cback = p_conn_cback; p_msg->p_ndef_cback = p_ndef_cback; if (p_listen_cfg) memcpy (&p_msg->listen_cfg, p_listen_cfg, sizeof (tNFA_LISTEN_CFG)); else memset (&p_msg->listen_cfg, 0x00, sizeof (tNFA_LISTEN_CFG)); nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_RegVSCback ** ** Description This function is called to register or de-register a callback ** function to receive Proprietary NCI response and notification ** events. ** The maximum number of callback functions allowed is NFC_NUM_VS_CBACKS ** ** Returns tNFC_STATUS ** *******************************************************************************/ tNFC_STATUS NFA_RegVSCback (BOOLEAN is_register, tNFA_VSC_CBACK *p_cback) { tNFA_DM_API_REG_VSC *p_msg; NFA_TRACE_API1 ("NFA_RegVSCback() is_register=%d", is_register); if (p_cback == NULL) { NFA_TRACE_ERROR0 ("NFA_RegVSCback() requires a valid callback function"); return (NFA_STATUS_FAILED); } if ((p_msg = (tNFA_DM_API_REG_VSC *) GKI_getbuf (sizeof(tNFA_DM_API_REG_VSC))) != NULL) { p_msg->hdr.event = NFA_DM_API_REG_VSC_EVT; p_msg->is_register = is_register; p_msg->p_cback = p_cback; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_Enable ** ** Description This function enables NFC. Prior to calling NFA_Enable, ** the NFCC must be powered up, and ready to receive commands. ** This function enables the tasks needed by NFC, opens the NCI ** transport, resets the NFC controller, downloads patches to ** the NFCC (if necessary), and initializes the NFC subsystems. ** ** This function should only be called once - typically when NFC ** is enabled during boot-up, or when NFC is enabled from a ** settings UI. Subsequent calls to NFA_Enable while NFA is ** enabling or enabled will be ignored. When the NFC startup ** procedure is completed, an NFA_DM_ENABLE_EVT is returned to the ** application using the tNFA_DM_CBACK. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_Enable (tNFA_DM_CBACK *p_dm_cback, tNFA_CONN_CBACK *p_conn_cback) { tNFA_DM_API_ENABLE *p_msg; NFA_TRACE_API0 ("NFA_Enable ()"); /* Validate parameters */ if ((!p_dm_cback) || (!p_conn_cback)) { NFA_TRACE_ERROR0 ("NFA_Enable (): error null callback"); return (NFA_STATUS_FAILED); } if ((p_msg = (tNFA_DM_API_ENABLE *) GKI_getbuf (sizeof (tNFA_DM_API_ENABLE))) != NULL) { p_msg->hdr.event = NFA_DM_API_ENABLE_EVT; p_msg->p_dm_cback = p_dm_cback; p_msg->p_conn_cback = p_conn_cback; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_EeDiscover ** ** Description This function retrieves the NFCEE information from NFCC. ** The NFCEE information is reported in NFA_EE_DISCOVER_EVT. ** ** This function may be called when a system supports removable ** NFCEEs, ** ** Returns NFA_STATUS_OK if information is retrieved successfully ** NFA_STATUS_FAILED If wrong state (retry later) ** NFA_STATUS_INVALID_PARAM If bad parameter ** *******************************************************************************/ tNFA_STATUS NFA_EeDiscover(tNFA_EE_CBACK *p_cback) { tNFA_EE_API_DISCOVER *p_msg; tNFA_STATUS status = NFA_STATUS_FAILED; NFA_TRACE_API0 ("NFA_EeDiscover()"); if (nfa_ee_cb.em_state != NFA_EE_EM_STATE_INIT_DONE) { NFA_TRACE_ERROR1 ("NFA_EeDiscover bad em state: %d", nfa_ee_cb.em_state); status = NFA_STATUS_FAILED; } else if ((nfa_ee_cb.p_ee_disc_cback != NULL) || (p_cback == NULL)) { NFA_TRACE_ERROR0 ("NFA_EeDiscover() in progress or NULL callback function"); status = NFA_STATUS_INVALID_PARAM; } else if ((p_msg = (tNFA_EE_API_DISCOVER *) GKI_getbuf (sizeof(tNFA_EE_API_DISCOVER))) != NULL) { p_msg->hdr.event = NFA_EE_API_DISCOVER_EVT; p_msg->p_cback = p_cback; nfa_sys_sendmsg (p_msg); status = NFA_STATUS_OK; } return status; }
/******************************************************************************* ** ** Function NFA_CeConfigureEseListenTech ** ** Description Configure listening for the Ese, using the specified ** technologies. ** ** Events will be notifed using the tNFA_CONN_CBACK ** (registered during NFA_Enable) ** ** The NFA_CE_ESE_LISTEN_CONFIGURED_EVT reports the status of the ** operation. ** ** Activation and deactivation are reported using the ** NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events ** ** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT ** should happen before calling this function ** ** Returns: ** NFA_STATUS_OK, if command accepted ** NFA_STATUS_FAILED: otherwise ** *******************************************************************************/ tNFA_STATUS NFA_CeConfigureEseListenTech (tNFA_HANDLE ee_handle, tNFA_TECHNOLOGY_MASK tech_mask) { #if (NFC_NFCEE_INCLUDED == TRUE) tNFA_CE_MSG *p_msg; NFA_TRACE_API1 ("NFA_CeConfigureEseListenTech () ee_handle = 0x%x", ee_handle); /* If tech_mask is zero, then app is disabling listening for specified uicc */ if (tech_mask == 0) { return (nfa_ce_api_deregister_listen (ee_handle, NFA_CE_LISTEN_INFO_ESE)); } /* Otherwise then app is configuring ese listen for the specificed technologies */ if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL) { p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT; p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_ESE; p_msg->reg_listen.ee_handle = ee_handle; p_msg->reg_listen.tech_mask = tech_mask; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } #else NFA_TRACE_ERROR0 ("NFA_CeConfigureEseListenTech () NFCEE related functions are not enabled!"); #endif return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_CeSetIsoDepListenTech ** ** Description Set the technologies (NFC-A and/or NFC-B) to listen for when ** NFA_CeConfigureLocalTag or NFA_CeDeregisterAidOnDH are called. ** ** By default (if this API is not called), NFA will listen ** for both NFC-A and NFC-B for ISODEP. ** ** Note: If listening for ISODEP on UICC, the DH listen callbacks ** may still get activate notifications for ISODEP if the reader/ ** writer selects an AID that is not routed to the UICC (regardless ** of whether A or B was disabled using NFA_CeSetIsoDepListenTech) ** ** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT ** should happen before calling this function ** ** Returns: ** NFA_STATUS_OK, if command accepted ** NFA_STATUS_FAILED: otherwise ** *******************************************************************************/ tNFA_STATUS NFA_CeSetIsoDepListenTech (tNFA_TECHNOLOGY_MASK tech_mask) { tNFA_CE_MSG *p_msg; tNFA_TECHNOLOGY_MASK use_mask = (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B); NFA_TRACE_API1 ("NFA_CeSetIsoDepListenTech (): 0x%x", tech_mask); if (((tech_mask & use_mask) == 0) || ((tech_mask & ~use_mask) != 0) ) { NFA_TRACE_ERROR0 ("NFA_CeSetIsoDepListenTech: Invalid technology mask"); return (NFA_STATUS_INVALID_PARAM); } if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL) { p_msg->hdr.event = NFA_CE_API_CFG_ISODEP_TECH_EVT; p_msg->hdr.layer_specific = tech_mask & use_mask; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function nfa_p2p_update_active_listen_timeout_cback ** ** Description Timeout while waiting for passive mode activation ** ** Returns void ** *******************************************************************************/ static void nfa_p2p_update_active_listen_timeout_cback (TIMER_LIST_ENT *p_tle) { NFA_TRACE_ERROR0 ("nfa_p2p_update_active_listen_timeout_cback()"); /* restore active listen mode */ nfa_p2p_update_active_listen (); }
/******************************************************************************* ** ** Function NFA_EeDisconnect ** ** Description Disconnect (if a connection is currently open) from an ** NFCEE interface. The result of this operation is reported ** with the NFA_EE_DISCONNECT_EVT. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** NFA_STATUS_INVALID_PARAM If bad parameter ** *******************************************************************************/ tNFA_STATUS NFA_EeDisconnect(tNFA_HANDLE ee_handle) { tNFA_EE_API_DISCONNECT *p_msg; tNFA_STATUS status = NFA_STATUS_FAILED; UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF); tNFA_EE_ECB *p_cb; NFA_TRACE_API1 ("NFA_EeDisconnect(): handle:<0x%x>", ee_handle); p_cb = nfa_ee_find_ecb (nfcee_id); if ((p_cb == NULL) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN)) { NFA_TRACE_ERROR0 ("NFA_EeDisconnect() Bad ee_handle"); status = NFA_STATUS_INVALID_PARAM; } else if ((p_msg = (tNFA_EE_API_DISCONNECT *) GKI_getbuf (sizeof(tNFA_EE_API_DISCONNECT))) != NULL) { p_msg->hdr.event = NFA_EE_API_DISCONNECT_EVT; p_msg->nfcee_id = nfcee_id; p_msg->p_cb = p_cb; nfa_sys_sendmsg (p_msg); status = NFA_STATUS_OK; } return status; }
/******************************************************************************* ** ** Function NFA_EeConnect ** ** Description Open connection to an NFCEE attached to the NFCC ** ** The status of this operation is ** reported with the NFA_EE_CONNECT_EVT. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** NFA_STATUS_INVALID_PARAM If bad parameter ** *******************************************************************************/ tNFA_STATUS NFA_EeConnect(tNFA_HANDLE ee_handle, UINT8 ee_interface, tNFA_EE_CBACK *p_cback) { tNFA_EE_API_CONNECT *p_msg; tNFA_STATUS status = NFA_STATUS_FAILED; UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF); tNFA_EE_ECB *p_cb; NFA_TRACE_API2 ("NFA_EeConnect(): handle:<0x%x> ee_interface:0x%x", ee_handle, ee_interface); p_cb = nfa_ee_find_ecb (nfcee_id); if ((p_cb == NULL) || (p_cback == NULL)) { NFA_TRACE_ERROR0 ("Bad ee_handle or NULL callback function"); status = NFA_STATUS_INVALID_PARAM; } else if ((p_msg = (tNFA_EE_API_CONNECT *) GKI_getbuf (sizeof(tNFA_EE_API_CONNECT))) != NULL) { p_msg->hdr.event = NFA_EE_API_CONNECT_EVT; p_msg->nfcee_id = nfcee_id; p_msg->p_cb = p_cb; p_msg->ee_interface = ee_interface; p_msg->p_cback = p_cback; nfa_sys_sendmsg (p_msg); status = NFA_STATUS_OK; } return status; }
/******************************************************************************* ** ** Function NFA_EeSendData ** ** Description Send data to the given NFCEE. ** This function shall be called after NFA_EE_CONNECT_EVT is reported ** and before NFA_EeDisconnect is called on the given ee_handle. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** NFA_STATUS_INVALID_PARAM If bad parameter ** *******************************************************************************/ tNFA_STATUS NFA_EeSendData (tNFA_HANDLE ee_handle, UINT16 data_len, UINT8 *p_data) { tNFA_EE_API_SEND_DATA *p_msg; tNFA_STATUS status = NFA_STATUS_FAILED; UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF); tNFA_EE_ECB *p_cb; NFA_TRACE_API1 ("NFA_EeSendData(): handle:<0x%x>", ee_handle); p_cb = nfa_ee_find_ecb (nfcee_id); if ((p_cb == NULL) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN) || (p_data == NULL)) { NFA_TRACE_ERROR0 ("Bad ee_handle or NULL data"); status = NFA_STATUS_INVALID_PARAM; } else if ((p_msg = (tNFA_EE_API_SEND_DATA *) GKI_getbuf ((UINT16)(sizeof(tNFA_EE_API_SEND_DATA) + data_len))) != NULL) { p_msg->hdr.event = NFA_EE_API_SEND_DATA_EVT; p_msg->nfcee_id = nfcee_id; p_msg->p_cb = p_cb; p_msg->data_len = data_len; p_msg->p_data = (UINT8 *)(p_msg + 1); memcpy(p_msg->p_data, p_data, data_len); nfa_sys_sendmsg (p_msg); status = NFA_STATUS_OK; } return status; }
/******************************************************************************* ** ** Function NFA_PowerOffSleepMode ** ** Description This function is called to enter or leave NFCC Power Off Sleep mode ** NFA_DM_PWR_MODE_CHANGE_EVT will be sent to indicate status. ** ** start_stop : TRUE if entering Power Off Sleep mode ** FALSE if leaving Power Off Sleep mode ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_PowerOffSleepMode (BOOLEAN start_stop) { BT_HDR *p_msg; NFA_TRACE_API1 ("NFA_PowerOffSleepState () start_stop=%d", start_stop); if (nfa_dm_cb.flags & NFA_DM_FLAGS_SETTING_PWR_MODE) { NFA_TRACE_ERROR0 ("NFA_PowerOffSleepState (): NFA DM is busy to update power mode"); return (NFA_STATUS_FAILED); } else { nfa_dm_cb.flags |= NFA_DM_FLAGS_SETTING_PWR_MODE; } if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL) { p_msg->event = NFA_DM_API_POWER_OFF_SLEEP_EVT; p_msg->layer_specific = start_stop; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_EeRemoveAidRouting ** ** Description This function is called to remove the given AID entry from the ** listen mode routing table. If the entry configures VS, ** it is also removed. The status of this operation is reported ** as the NFA_EE_REMOVE_AID_EVT. ** ** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT ** should happen before calling this function ** ** Note: NFA_EeUpdateNow() should be called after last NFA-EE function ** to change the listen mode routing is called. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** NFA_STATUS_INVALID_PARAM If bad parameter ** *******************************************************************************/ tNFA_STATUS NFA_EeRemoveAidRouting(UINT8 aid_len, UINT8 *p_aid) { tNFA_EE_API_REMOVE_AID *p_msg; tNFA_STATUS status = NFA_STATUS_FAILED; UINT16 size = sizeof(tNFA_EE_API_REMOVE_AID) + aid_len; NFA_TRACE_API0 ("NFA_EeRemoveAidRouting()"); if ((aid_len == 0) || (p_aid == NULL) || (aid_len > NFA_MAX_AID_LEN)) { NFA_TRACE_ERROR0 ("Bad AID"); status = NFA_STATUS_INVALID_PARAM; } else if ((p_msg = (tNFA_EE_API_REMOVE_AID *) GKI_getbuf (size)) != NULL) { p_msg->hdr.event = NFA_EE_API_REMOVE_AID_EVT; p_msg->aid_len = aid_len; p_msg->p_aid = (UINT8 *)(p_msg + 1); memcpy(p_msg->p_aid, p_aid, aid_len); nfa_sys_sendmsg (p_msg); status = NFA_STATUS_OK; } return status; }
/******************************************************************************* ** ** Function NFA_EeSetDefaultProtoRouting ** ** Description This function is called to add, change or remove the ** default routing based on Protocol in the listen mode routing ** table for the given ee_handle. The status of this ** operation is reported as the NFA_EE_SET_PROTO_CFG_EVT. ** ** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT ** should happen before calling this function ** ** Note: NFA_EeUpdateNow() should be called after last NFA-EE function ** to change the listen mode routing is called. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** NFA_STATUS_INVALID_PARAM If bad parameter ** *******************************************************************************/ tNFA_STATUS NFA_EeSetDefaultProtoRouting(tNFA_HANDLE ee_handle, tNFA_PROTOCOL_MASK protocols_switch_on, tNFA_PROTOCOL_MASK protocols_switch_off, tNFA_PROTOCOL_MASK protocols_battery_off) { tNFA_EE_API_SET_PROTO_CFG *p_msg; tNFA_STATUS status = NFA_STATUS_FAILED; UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF); tNFA_EE_ECB *p_cb; NFA_TRACE_API4 ("NFA_EeSetDefaultProtoRouting(): handle:<0x%x>protocol_mask:<0x%x>/<0x%x>/<0x%x>", ee_handle, protocols_switch_on, protocols_switch_off, protocols_battery_off); p_cb = nfa_ee_find_ecb (nfcee_id); if (p_cb == NULL) { NFA_TRACE_ERROR0 ("Bad ee_handle"); status = NFA_STATUS_INVALID_PARAM; } else if ((p_msg = (tNFA_EE_API_SET_PROTO_CFG *) GKI_getbuf (sizeof(tNFA_EE_API_SET_PROTO_CFG))) != NULL) { p_msg->hdr.event = NFA_EE_API_SET_PROTO_CFG_EVT; p_msg->nfcee_id = nfcee_id; p_msg->p_cb = p_cb; p_msg->protocols_switch_on = protocols_switch_on; p_msg->protocols_switch_off = protocols_switch_off; p_msg->protocols_battery_off = protocols_battery_off; nfa_sys_sendmsg (p_msg); status = NFA_STATUS_OK; } return status; }
/******************************************************************************* ** ** Function NFA_RegisterNDefUriHandler ** ** Description This API is a special-case of NFA_RegisterNDefTypeHandler ** with TNF=NFA_TNF_WKT, and type_name='U' (URI record); and allows ** registering for specific URI types (e.g. 'tel:' or 'mailto:'). ** ** An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK ** to indicate that registration was successful, and provide a ** handle for this registration. ** ** If uri_id=NFA_NDEF_URI_ID_ABSOLUTE, then p_abs_uri contains the ** unabridged URI. For all other uri_id values, the p_abs_uri ** parameter is ignored (i.e the URI prefix is implied by uri_id). ** See [NFC RTD URI] for more information. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ NFC_API extern tNFA_STATUS NFA_RegisterNDefUriHandler (BOOLEAN handle_whole_message, tNFA_NDEF_URI_ID uri_id, UINT8 *p_abs_uri, UINT8 uri_id_len, tNFA_NDEF_CBACK *p_ndef_cback) { tNFA_DM_API_REG_NDEF_HDLR *p_msg; NFA_TRACE_API2 ("NFA_RegisterNDefUriHandler (): handle whole ndef message: %i, uri_id=0x%02x", handle_whole_message, uri_id); /* Check for NULL callback */ if (!p_ndef_cback) { NFA_TRACE_ERROR0 ("NFA_RegisterNDefUriHandler (): error - null callback"); return (NFA_STATUS_INVALID_PARAM); } if ((p_msg = (tNFA_DM_API_REG_NDEF_HDLR *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_REG_NDEF_HDLR) + uri_id_len))) != NULL) { p_msg->hdr.event = NFA_DM_API_REG_NDEF_HDLR_EVT; p_msg->flags = NFA_NDEF_FLAGS_WKT_URI; if (handle_whole_message) { p_msg->flags |= NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE; } /* abs_uri is only valid fir uri_id=NFA_NDEF_URI_ID_ABSOLUTE */ if (uri_id != NFA_NDEF_URI_ID_ABSOLUTE) { uri_id_len = 0; } p_msg->tnf = NFA_TNF_WKT; p_msg->uri_id = uri_id; p_msg->name_len = uri_id_len; p_msg->p_ndef_cback = p_ndef_cback; memcpy (p_msg->name, p_abs_uri, uri_id_len); nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_EeGetInfo ** ** Description This function retrieves the NFCEE information from NFA. ** The actual number of NFCEE is returned in p_num_nfcee ** and NFCEE information is returned in p_info ** ** Returns NFA_STATUS_OK if information is retrieved successfully ** NFA_STATUS_FAILED If wrong state (retry later) ** NFA_STATUS_INVALID_PARAM If bad parameter ** *******************************************************************************/ tNFA_STATUS NFA_EeGetInfo(UINT8 *p_num_nfcee, tNFA_EE_INFO *p_info) { int xx, ret = nfa_ee_cb.cur_ee; tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb; UINT8 max_ret; UINT8 num_ret = 0; NFA_TRACE_DEBUG2 ("NFA_EeGetInfo em_state:%d cur_ee:%d", nfa_ee_cb.em_state, nfa_ee_cb.cur_ee); /* validate parameters */ if (p_info == NULL || p_num_nfcee == NULL) { NFA_TRACE_ERROR0 ("NFA_EeGetInfo bad parameter"); return (NFA_STATUS_INVALID_PARAM); } max_ret = *p_num_nfcee; *p_num_nfcee = 0; if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT) { NFA_TRACE_ERROR1 ("NFA_EeGetInfo bad em state: %d", nfa_ee_cb.em_state); return (NFA_STATUS_FAILED); } /* compose output */ for (xx = 0; (xx < ret) && (num_ret < max_ret); xx++, p_cb++) { NFA_TRACE_DEBUG4 ("xx:%d max_ret:%d, num_ret:%d ee_status:0x%x", xx, max_ret, num_ret, p_cb->ee_status); if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) || (p_cb->ee_status == NFA_EE_STATUS_REMOVED)) { continue; } p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id; p_info->ee_status = p_cb->ee_status; p_info->num_interface = p_cb->num_interface; p_info->num_tlvs = p_cb->num_tlvs; memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface); memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV)); p_info++; num_ret++; } NFA_TRACE_DEBUG1 ("num_ret:%d", num_ret); *p_num_nfcee = num_ret; return (NFA_STATUS_OK); }
/******************************************************************************* ** ** Function NFA_ReleaseExclusiveRfControl ** ** Description Release exclusive control of NFC. Once released, behavior ** prior to obtaining exclusive RF control will resume. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_ReleaseExclusiveRfControl (void) { BT_HDR *p_msg; NFA_TRACE_API0 ("NFA_ReleaseExclusiveRfControl ()"); if (!nfa_dm_cb.p_excl_conn_cback) { NFA_TRACE_ERROR0 ("NFA_ReleaseExclusiveRfControl (): Exclusive rf control is not in progress"); return (NFA_STATUS_FAILED); } if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL) { p_msg->event = NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/****************************************************************************** ** ** Function NFA_EeUpdateNow ** ** Description This function is called to send the current listen mode ** routing table and VS configuration to the NFCC (without waiting ** for NFA_EE_ROUT_TIMEOUT_VAL). ** ** The status of this operation is ** reported with the NFA_EE_UPDATED_EVT. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_SEMANTIC_ERROR is update is currently in progress ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_EeUpdateNow(void) { BT_HDR *p_msg; tNFA_STATUS status = NFA_STATUS_FAILED; NFA_TRACE_API0 ("NFA_EeUpdateNow()"); if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE_ALL) { NFA_TRACE_ERROR0 ("update in progress"); status = NFA_STATUS_SEMANTIC_ERROR; } else if ((p_msg = (BT_HDR *) GKI_getbuf (BT_HDR_SIZE)) != NULL) { p_msg->event = NFA_EE_API_UPDATE_NOW_EVT; nfa_sys_sendmsg (p_msg); status = NFA_STATUS_OK; } return status; }
/******************************************************************************* ** ** Function NFA_EeRegister ** ** Description This function registers a callback function to receive the ** events from NFA-EE module. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** NFA_STATUS_INVALID_PARAM If bad parameter ** *******************************************************************************/ tNFA_STATUS NFA_EeRegister(tNFA_EE_CBACK *p_cback) { tNFA_EE_API_REGISTER *p_msg; tNFA_STATUS status = NFA_STATUS_FAILED; NFA_TRACE_API0 ("NFA_EeRegister()"); if (p_cback == NULL) { NFA_TRACE_ERROR0 ("NFA_EeRegister(): with NULL callback function"); status = NFA_STATUS_INVALID_PARAM; } else if ((p_msg = (tNFA_EE_API_REGISTER *) GKI_getbuf (sizeof(tNFA_EE_API_REGISTER))) != NULL) { p_msg->hdr.event = NFA_EE_API_REGISTER_EVT; p_msg->p_cback = p_cback; nfa_sys_sendmsg (p_msg); status = NFA_STATUS_OK; } return status; }
/******************************************************************************* ** ** Function nfa_dm_check_set_config ** ** Description Update config parameters only if it's different from NFCC ** ** ** Returns tNFA_STATUS ** *******************************************************************************/ tNFA_STATUS nfa_dm_check_set_config (UINT8 tlv_list_len, UINT8 *p_tlv_list, BOOLEAN app_init) { UINT8 type, len, *p_value, *p_stored = NULL, max_len = 0; UINT8 xx = 0, updated_len = 0, *p_cur_len; BOOLEAN update; tNFC_STATUS nfc_status; UINT32 cur_bit; NFA_TRACE_DEBUG0 ("nfa_dm_check_set_config ()"); /* We only allow 32 pending SET_CONFIGs */ if (nfa_dm_cb.setcfg_pending_num >= NFA_DM_SETCONFIG_PENDING_MAX) { NFA_TRACE_ERROR0 ("nfa_dm_check_set_config () error: pending number of SET_CONFIG exceeded"); return NFA_STATUS_FAILED; } while (tlv_list_len - xx >= 2) /* at least type and len */ { update = FALSE; type = *(p_tlv_list + xx); len = *(p_tlv_list + xx + 1); p_value = p_tlv_list + xx + 2; p_cur_len = NULL; switch (type) { case NFC_PMID_TOTAL_DURATION: p_stored = nfa_dm_cb.params.total_duration; max_len = NCI_PARAM_LEN_TOTAL_DURATION; break; /* ** Listen A Configuration */ case NFC_PMID_LA_BIT_FRAME_SDD: p_stored = nfa_dm_cb.params.la_bit_frame_sdd; max_len = NCI_PARAM_LEN_LA_BIT_FRAME_SDD; p_cur_len = &nfa_dm_cb.params.la_bit_frame_sdd_len; break; case NFC_PMID_LA_PLATFORM_CONFIG: p_stored = nfa_dm_cb.params.la_platform_config; max_len = NCI_PARAM_LEN_LA_PLATFORM_CONFIG; p_cur_len = &nfa_dm_cb.params.la_platform_config_len; break; case NFC_PMID_LA_SEL_INFO: p_stored = nfa_dm_cb.params.la_sel_info; max_len = NCI_PARAM_LEN_LA_SEL_INFO; p_cur_len = &nfa_dm_cb.params.la_sel_info_len; break; case NFC_PMID_LA_NFCID1: p_stored = nfa_dm_cb.params.la_nfcid1; max_len = NCI_NFCID1_MAX_LEN; p_cur_len = &nfa_dm_cb.params.la_nfcid1_len; break; case NFC_PMID_LA_HIST_BY: p_stored = nfa_dm_cb.params.la_hist_by; max_len = NCI_MAX_HIS_BYTES_LEN; p_cur_len = &nfa_dm_cb.params.la_hist_by_len; break; /* ** Listen B Configuration */ case NFC_PMID_LB_SENSB_INFO: #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) if(app_init == TRUE) { #endif p_stored = nfa_dm_cb.params.lb_sensb_info; max_len = NCI_PARAM_LEN_LB_SENSB_INFO; p_cur_len = &nfa_dm_cb.params.lb_sensb_info_len; #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) } else { update = FALSE; } #endif break; case NFC_PMID_LB_NFCID0: p_stored = nfa_dm_cb.params.lb_nfcid0; max_len = NCI_PARAM_LEN_LB_NFCID0; p_cur_len = &nfa_dm_cb.params.lb_nfcid0_len; break; case NFC_PMID_LB_APPDATA: p_stored = nfa_dm_cb.params.lb_appdata; max_len = NCI_PARAM_LEN_LB_APPDATA; p_cur_len = &nfa_dm_cb.params.lb_appdata_len; break; case NFC_PMID_LB_ADC_FO: p_stored = nfa_dm_cb.params.lb_adc_fo; max_len = NCI_PARAM_LEN_LB_ADC_FO; p_cur_len = &nfa_dm_cb.params.lb_adc_fo_len; break; case NFC_PMID_LB_H_INFO: p_stored = nfa_dm_cb.params.lb_h_info; max_len = NCI_MAX_ATTRIB_LEN; p_cur_len = &nfa_dm_cb.params.lb_h_info_len; break; /* ** Listen F Configuration */ case NFC_PMID_LF_PROTOCOL: p_stored = nfa_dm_cb.params.lf_protocol; max_len = NCI_PARAM_LEN_LF_PROTOCOL; p_cur_len = &nfa_dm_cb.params.lf_protocol_len; break; case NFC_PMID_LF_T3T_FLAGS2: p_stored = nfa_dm_cb.params.lf_t3t_flags2; max_len = NCI_PARAM_LEN_LF_T3T_FLAGS2; p_cur_len = &nfa_dm_cb.params.lf_t3t_flags2_len; break; // LF_T3T_PMM is not supported. /* case NFC_PMID_LF_T3T_PMM: p_stored = nfa_dm_cb.params.lf_t3t_pmm; max_len = NCI_PARAM_LEN_LF_T3T_PMM; break;*/ /* ** ISO-DEP and NFC-DEP Configuration */ #if(NFC_NXP_NOT_OPEN_INCLUDED != TRUE) case NFC_PMID_FWI: p_stored = nfa_dm_cb.params.fwi; max_len = NCI_PARAM_LEN_FWI; break; #endif case NFC_PMID_WT: p_stored = nfa_dm_cb.params.wt; max_len = NCI_PARAM_LEN_WT; break; case NFC_PMID_ATR_REQ_GEN_BYTES: p_stored = nfa_dm_cb.params.atr_req_gen_bytes; max_len = NCI_MAX_GEN_BYTES_LEN; p_cur_len = &nfa_dm_cb.params.atr_req_gen_bytes_len; break; case NFC_PMID_ATR_RES_GEN_BYTES: p_stored = nfa_dm_cb.params.atr_res_gen_bytes; max_len = NCI_MAX_GEN_BYTES_LEN; p_cur_len = &nfa_dm_cb.params.atr_res_gen_bytes_len; break; default: /* ** Listen F Configuration */ if ((type >= NFC_PMID_LF_T3T_ID1) && (type < NFC_PMID_LF_T3T_ID1 + NFA_CE_LISTEN_INFO_MAX)) { p_stored = nfa_dm_cb.params.lf_t3t_id[type - NFC_PMID_LF_T3T_ID1]; max_len = NCI_PARAM_LEN_LF_T3T_ID; } else { /* we don't stored this config items */ update = TRUE; p_stored = NULL; } break; } if ((p_stored)&&(len <= max_len)) { if (p_cur_len) { if (*p_cur_len != len) { *p_cur_len = len; update = TRUE; } else if (memcmp (p_value, p_stored, len)) { update = TRUE; } } else if (len == max_len) /* fixed length */ { if (memcmp (p_value, p_stored, len)) { update = TRUE; } } } if (update) { /* we don't store this type */ if (p_stored) { memcpy (p_stored, p_value, len); } /* If need to change TLV in the original list. (Do not modify list if app_init) */ if ((updated_len != xx) && (!app_init)) { memcpy (p_tlv_list + updated_len, p_tlv_list + xx, (len + 2)); } updated_len += (len + 2); } xx += len + 2; /* move to next TLV */ } /* If any TVLs to update, or if the SetConfig was initiated by the application, then send the SET_CONFIG command */ //if (updated_len || app_init) /*Commented to fix the hack*/ if #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) (( #endif (updated_len || app_init) #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) && (appl_dta_mode_flag == 0x00 )) || ((appl_dta_mode_flag) && (app_init))) #endif { if ((nfc_status = NFC_SetConfig (updated_len, p_tlv_list)) == NFC_STATUS_OK) { /* Keep track of whether we will need to notify NFA_DM_SET_CONFIG_EVT on NFC_SET_CONFIG_REVT */ /* Get the next available bit offset for this setconfig (based on how many SetConfigs are outstanding) */ cur_bit = (UINT32) (1 << nfa_dm_cb.setcfg_pending_num); /* If setconfig is due to NFA_SetConfig: then set the bit (NFA_DM_SET_CONFIG_EVT needed on NFC_SET_CONFIG_REVT) */ if (app_init) { nfa_dm_cb.setcfg_pending_mask |= cur_bit; } /* Otherwise setconfig is internal: clear the bit (NFA_DM_SET_CONFIG_EVT not needed on NFC_SET_CONFIG_REVT) */ else { nfa_dm_cb.setcfg_pending_mask &= ~cur_bit; } /* Increment setcfg_pending counter */ nfa_dm_cb.setcfg_pending_num++; } return (nfc_status); } else { return NFA_STATUS_OK; } }
/******************************************************************************* ** ** Function nfa_hciu_send_msg ** ** Description This function will fragment the given packet, if necessary ** and send it on the given pipe. ** ** Returns status ** *******************************************************************************/ tNFA_STATUS nfa_hciu_send_msg (UINT8 pipe_id, UINT8 type, UINT8 instruction, UINT16 msg_len, UINT8 *p_msg) { BT_HDR *p_buf; UINT8 *p_data; BOOLEAN first_pkt = TRUE; UINT16 data_len; tNFA_STATUS status = NFA_STATUS_OK; UINT16 max_seg_hcp_pkt_size = nfa_hci_cb.buff_size; #if (BT_TRACE_VERBOSE == TRUE) char buff[100]; NFA_TRACE_DEBUG3 ("nfa_hciu_send_msg pipe_id:%d %s len:%d", pipe_id, nfa_hciu_get_type_inst_names (pipe_id, type, instruction, buff), msg_len); #else NFA_TRACE_DEBUG4 ("nfa_hciu_send_msg pipe_id:%d Type: %u Inst: %u len: %d", pipe_id, type, instruction, msg_len); #endif if (instruction == NFA_HCI_ANY_GET_PARAMETER) nfa_hci_cb.param_in_use = *p_msg; while ((first_pkt == TRUE) || (msg_len != 0)) { if ((p_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL) { p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; /* First packet has a 2-byte header, subsequent fragments have a 1-byte header */ data_len = first_pkt ? (max_seg_hcp_pkt_size - 2) : (max_seg_hcp_pkt_size - 1); p_data = (UINT8 *) (p_buf + 1) + p_buf->offset; /* Last or only segment has "no fragmentation" bit set */ if (msg_len > data_len) { *p_data++ = (NFA_HCI_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F); } else { data_len = msg_len; *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F); } p_buf->len = 1; /* Message header only goes in the first segment */ if (first_pkt) { first_pkt = FALSE; *p_data++ = (type << 6) | instruction; p_buf->len++; } if (data_len != 0) { memcpy (p_data, p_msg, data_len); p_buf->len += data_len; msg_len -= data_len; if (msg_len > 0) p_msg += data_len; } #if (BT_TRACE_PROTOCOL == TRUE) DispHcp (((UINT8 *) (p_buf + 1) + p_buf->offset), p_buf->len, FALSE, (BOOLEAN) ((p_buf->len - data_len) == 2)); #endif if (HCI_LOOPBACK_DEBUG) handle_debug_loopback (p_buf, pipe_id, type, instruction); else status = NFC_SendData (nfa_hci_cb.conn_id, p_buf); } else { NFA_TRACE_ERROR0 ("nfa_hciu_send_data_packet no buffers"); status = NFA_STATUS_NO_BUFFERS; break; } } /* Start timer if response to wait for a particular time for the response */ if (type == NFA_HCI_COMMAND_TYPE) { nfa_hci_cb.cmd_sent = instruction; if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP; nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout); } return status; }