FreeCalypso > hg > freecalypso-sw
diff gsm-fw/g23m-aci/bat/bat_adp.c @ 775:eedbf248bac0
gsm-fw/g23m-aci subtree: initial import from LoCosto source
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 12 Oct 2014 01:45:14 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/g23m-aci/bat/bat_adp.c Sun Oct 12 01:45:14 2014 +0000 @@ -0,0 +1,231 @@ +/* ++----------------------------------------------------------------------------- +| Project : +| Modul : BAT ++----------------------------------------------------------------------------- +| Copyright 2005 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : This Modul holds the functions used by GDD +| for the binary AT command library ++----------------------------------------------------------------------------- +*/ + +#define _BAT_ADP_C_ + +#include "typedefs.h" +#include "gdd.h" +#include "l2p_types.h" +#include "l2p.h" +#include "bat.h" +#include "bat_ctrl.h" +#include "bat_intern.h" + + +/* ++----------------------------------------------------------------------------+ +| PROJECT : MODULE : BINARY AT COMMAND LIBRARY | +| STATE : code ROUTINE : bat_gdd_receive_data_cb | ++----------------------------------------------------------------------------+ +PURPOSE : + This function is called by GDD when itself received new data from PSI. + It will pass a GDD buffer (linked list), which has the following speciality: + - the first list element is reserved and BAT Lib has to follow the next pointer + to see the "first" user data. + - such a user data element is passed by BAT Lib to L2P. L2P added at the sender + side its own header, which maintains possibly fragmentation. If the received + data have been fragmented by L2P at the sender side, then L2P itself iterates + over the GDD linked list by calling bat_l2p_get_next_buf_seg() here at receiver side. + When L2P has reassembled from several segments/list element the complete user data, + then it passes this complete data to BAT Lib. + - BUT THERE IS AN ADDITIONAL SCENARIO: + ACI was not able to send the data to PSI/GDD. Then ACI also builds up a linked list + until it is able to send to PSI/GDD. + Every list element represents one response/indication, which itself could be fragmented by L2P. + Assume the following scenario: + The connection between ACI and PSI was not available. + ACI received three indications from the protocol stack, where the second one is too large so that + L2P must split it into two segments. That means that ACI has built a linked list of four + elements, which represents three logical data unit. The first list element belongs to the + first indication, the second and third list element belongs to the second indication + and the fourth list element belongs to the third indication. +*/ + +GDD_RESULT bat_gdd_receive_data_cb (T_GDD_CON_HANDLE con, T_GDD_BUF *buf) +{ + T_BAT_instance inst_hndl = BAT_BROADCAST_CHANNEL; + T_BAT_instance_maintain *inst_mt = NULL; + + BAT_TRACE_FUNCTION ("bat_gdd_receive_data_cb()"); + BAT_TRACE_EVENT_P2 ("data received from GDD has length: %d, has c_segment %d", buf->length, buf->c_segment); + + /* if the info is for an unknown instance, return OK, GDD can only handle ok and busy, + so in error cases, GDD_OK will be returned */ + if (bat_get_instance_from_gdd_handle(con, &inst_hndl, &inst_mt)) + { + /* if instance is unknown, BAT Lib ignores the data and returns OK to GDD */ + BAT_TRACE_ERROR("bat_gdd_receive_data_cb(): Data from unknown instance received!"); + return (GDD_OK); + } + + /* if the instance is not initialized */ + if (inst_mt->instance_state EQ BAT_INSTANCE_IDLE) + { + /* if instance is not initialized, BAT Lib ignores the data and returns OK to GDD */ + BAT_TRACE_ERROR ("bat_gdd_receive_data_cb(): Data is received from GDD for an uninitialized instance."); + return (GDD_OK); + } + + /* check if the receiver buffer is free, if not return a busy signal to GDD, BAT Lib will + send a ready signal to GDD when the buffer is freed (BAT Lib will receive ctrl info from) + app, see bat_ctrl() */ + if (inst_mt->buffer.buf_st EQ BAT_BUF_FILLED) + { + BAT_TRACE_EVENT ("bat_gdd_receive_data_cb(): receive buffer is not yet freed!"); + return (GDD_BUSY); + } + + bat_l2p_receive(inst_hndl, buf); + + return (GDD_OK); +} + + +LOCAL void bat_check_clients_for_busy (T_BAT_instance_maintain *instance, T_BAT_instance inst_hndl) +{ + T_BAT_client_maintain *clnt_mt = NULL; + T_BAT_client clnt_hndl = BAT_INVALID_CLIENT_HANDLE; + int i; + + for (i = 0; i < instance->max_client_num; i++) + { + clnt_hndl = MAKE_CLNT_HNDL(i, inst_hndl); + bat_get_client_from_client_handle(clnt_hndl, &clnt_mt); + switch (clnt_mt->client_state) + { + case (BAT_CLIENT_BUSY): + { + clnt_mt->signal_cb (clnt_hndl, BAT_READY_RESOURCE); + bat_change_client_state(clnt_mt, BAT_CLIENT_READY); + break; + } + case (BAT_CLIENT_SENDING_AND_BUSY): + { + clnt_mt->signal_cb (clnt_hndl, BAT_READY_RESOURCE); + bat_change_client_state(clnt_mt, BAT_CLIENT_SENDING); + break; + } + default: + break; + } + } +} + +/* ++----------------------------------------------------------------------------+ +| PROJECT : MODULE : BINARY AT COMMAND LIBRARY | +| STATE : code ROUTINE : bat_gdd_signal_cb | ++----------------------------------------------------------------------------+ +PURPOSE : + This function is called by GDD for signalling of control information between + BAT Lib and GDD. + +*/ +void bat_gdd_signal_cb(T_GDD_CON_HANDLE con, T_GDD_SIGNAL signal) +{ + T_BAT_instance_maintain *instance = NULL; + T_BAT_instance inst_hndl = BAT_INVALID_INSTANCE_HANDLE; + T_BATC_signal ctrl_data; + T_BATC_max_clients max_clnt; + + BAT_TRACE_FUNCTION ("bat_gdd_signal_cb()"); + BAT_TRACE_EVENT_P1 ("bat_gdd_signal_cb(): con_hndl searched for is %x", con); + + if (bat_get_instance_from_gdd_handle(con, &inst_hndl, &instance)) + { + BAT_TRACE_ERROR ("bat_gdd_signal_cb(): gdd handle is not found, ignore signal"); + return; + } + + switch (signal.sig) + { + case (GDD_SIGTYPE_CONNECTION_OPENED): + case (GDD_SIGTYPE_SEND_BUF_AVAILABLE): + { + BAT_TRACE_EVENT ("bat_gdd_signal_cb(): GDD_SIGTYPE_SEND_BUF_AVAILABLE received from GDD"); + + switch (instance->instance_state) + { + case (BAT_INSTANCE_IDLE): + { + /* update the instance state */ + bat_change_instance_state(instance, BAT_INSTANCE_ACTIVATING); + + /* BAT sends out the control info to ACI*/ + ctrl_data.ctrl_params = BATC_MAX_CLIENTS; + max_clnt.num_clients = instance->max_client_num; + ctrl_data.params.ptr_max_clients = &max_clnt; + + if (bat_send_ctrl_data(inst_hndl, &ctrl_data) NEQ BAT_OK) + { + BAT_TRACE_ERROR ("bat_gdd_signal_cb(): BAT new fails to send ctrl info, connection can not be open"); + + if (instance->config->adapter.gdd_if.gdd_disconnect(con)) + { + BAT_TRACE_ERROR ("bat_gdd_signal_cb(): GDD returns error when disconnecting."); + } + instance->instance_signal_cb(BAT_NEW_INSTANCE_FAIL); + bat_deinit_instance_pointer(inst_hndl); + } + break; + } + /* flow control for client channels, GDD state has be changed from BUSY to READY */ + case (BAT_INSTANCE_READY): + { + bat_check_clients_for_busy(instance, inst_hndl); + break; + } + /* flow control for instance, bat_open() hasn't been succesful yet */ + case (BAT_INSTANCE_BUSY): + { + instance->instance_signal_cb (BAT_READY_RESOURCE); + bat_change_instance_state(instance, BAT_INSTANCE_READY); + break; + } + default: + { + return; + } + } + break; + } + case (GDD_SIGTYPE_CONNECTION_FAILED): + { + BAT_TRACE_ERROR("bat_gdd_signal_cb(): GDD_SIGTYPE_CONNECTION_OPENED_FAILED received from GDD"); + if (instance->config->adapter.gdd_if.gdd_disconnect(con)) + { + BAT_TRACE_ERROR ("bat_gdd_signal_cb(): GDD returns error when disconnecting."); + } + instance->instance_signal_cb (BAT_NEW_INSTANCE_FAIL); + bat_deinit_instance_pointer(inst_hndl); + L2P_Remove (inst_hndl); + break; + } + /* ignore other signal types */ + default: + { + break; + } + } + return; +} + +