1
6
7
16
17
18
19
20
21
22
23
24
25
36
37
48
49
61
62
67
68
80
81
86
87
88
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
118
119
124
125
133
139
145
158
169
170
171
172
173
177
178
182
183
184
185
186
187
188
191
192
193
199
200
203
204
205
206
210
211
/* ... */
#include <string.h>
#include "osi/osi.h"
#include "osi/allocator.h"
#include "common/bt_target.h"
#include "stack/obex_api.h"
#include "obex_int.h"
#include "obex_tl.h"7 includes
#if (OBEX_INCLUDED == TRUE)
#if OBEX_DYNAMIC_MEMORY == FALSE
tOBEX_CB obex_cb;
#else
tOBEX_CB *obex_cb_ptr = NULL;
#endif
static tOBEX_CCB *obex_find_ccb_by_tl_hdl(UINT8 tl, UINT16 tl_hdl)
{
tOBEX_CCB *p_ccb = NULL;
for (int i = 0; i < OBEX_MAX_CONNECTION; ++i) {
if (obex_cb.ccb[i].allocated && obex_cb.ccb[i].tl == tl && obex_cb.ccb[i].tl_hdl == tl_hdl) {
p_ccb = &obex_cb.ccb[i];
break;
}{...}
}{...}
return p_ccb;
}{...}
static tOBEX_SCB *obex_find_scb_by_tl_hdl(UINT8 tl, UINT16 tl_hdl)
{
tOBEX_SCB *p_scb = NULL;
for (int i = 0; i < OBEX_MAX_SERVER; ++i) {
if (obex_cb.scb[i].allocated && obex_cb.scb[i].tl == tl && obex_cb.scb[i].tl_hdl == tl_hdl) {
p_scb = &obex_cb.scb[i];
break;
}{...}
}{...}
return p_scb;
}{...}
tOBEX_CCB *obex_allocate_ccb(void)
{
tOBEX_CCB *p_ccb = NULL;
for (int i = 0; i < OBEX_MAX_CONNECTION; ++i) {
if (!obex_cb.ccb[i].allocated) {
obex_cb.ccb[i].allocated = i + 1;
p_ccb = &obex_cb.ccb[i];
break;
}{...}
}{...}
return p_ccb;
}{...}
void obex_free_ccb(tOBEX_CCB *p_ccb)
{
assert(p_ccb->allocated != 0);
memset(p_ccb, 0, sizeof(tOBEX_CCB));
}{...}
tOBEX_SCB *obex_allocate_scb(void)
{
tOBEX_SCB *p_scb = NULL;
for (int i = 0; i < OBEX_MAX_SERVER; ++i) {
if (!obex_cb.scb[i].allocated) {
obex_cb.scb[i].allocated = i + 1;
p_scb = &obex_cb.scb[i];
break;
}{...}
}{...}
return p_scb;
}{...}
void obex_free_scb(tOBEX_SCB *p_scb)
{
assert(p_scb->allocated != 0);
memset(p_scb, 0, sizeof(tOBEX_SCB));
}{...}
static bool check_conn_mtu_valid(tOBEX_CCB *p_ccb, BOOLEAN call_cb)
{
if (p_ccb->tl_our_mtu < 255 || p_ccb->tl_peer_mtu < 255) {
if (call_cb && p_ccb->callback) {
p_ccb->callback(p_ccb->allocated, OBEX_DISCONNECT_EVT, NULL);
}{...}
OBEX_TRACE_ERROR("Check OBEX transport layer MTU failed, disconnect");
obex_cb.tl_ops[p_ccb->tl]->disconnect(p_ccb->tl_hdl);
obex_free_ccb(p_ccb);
return false;
}{...}
return true;
}{...}
void obex_tl_evt_handler(UINT8 tl, tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg)
{
UINT16 tl_hdl = msg->any.hdl;
tOBEX_CCB *p_ccb = obex_find_ccb_by_tl_hdl(tl, tl_hdl);
tOBEX_SCB *p_scb = NULL;
tOBEX_MSG cb_msg = {0};
switch (evt)
{
case OBEX_TL_CONN_OPEN_EVT:
assert(p_ccb != NULL);
p_ccb->tl_peer_mtu = msg->conn_open.peer_mtu;
p_ccb->tl_our_mtu = msg->conn_open.our_mtu;
if (!check_conn_mtu_valid(p_ccb, TRUE)) {
break;
}{...}
p_ccb->state = OBEX_STATE_OPENED;
if (p_ccb->callback) {
cb_msg.connect.peer_mtu = msg->conn_open.peer_mtu;
cb_msg.connect.our_mtu = msg->conn_open.our_mtu;
p_ccb->callback(p_ccb->allocated, OBEX_CONNECT_EVT, &cb_msg);
}{...}
break;...
case OBEX_TL_DIS_CONN_EVT:
if (p_ccb != NULL) {
if (p_ccb->callback) {
p_ccb->callback(p_ccb->allocated, OBEX_DISCONNECT_EVT, NULL);
}{...}
obex_free_ccb(p_ccb);
}{...}
break;...
case OBEX_TL_CONGEST_EVT:
assert(p_ccb != NULL);
if (p_ccb->callback) {
p_ccb->callback(p_ccb->allocated, OBEX_CONGEST_EVT, NULL);
}{...}
break;...
case OBEX_TL_UNCONGEST_EVT:
assert(p_ccb != NULL);
if (p_ccb->callback) {
p_ccb->callback(p_ccb->allocated, OBEX_UNCONGEST_EVT, NULL);
}{...}
break;...
case OBEX_TL_MTU_CHANGE_EVT:
assert(p_ccb != NULL);
p_ccb->tl_peer_mtu = msg->mtu_chg.peer_mtu;
p_ccb->tl_our_mtu = msg->mtu_chg.our_mtu;
if (!check_conn_mtu_valid(p_ccb, TRUE)) {
break;
}{...}
if (p_ccb->callback) {
cb_msg.mtu_change.peer_mtu = msg->mtu_chg.peer_mtu;
cb_msg.mtu_change.our_mtu = msg->mtu_chg.our_mtu;
p_ccb->callback(p_ccb->allocated, OBEX_MTU_CHANGE_EVT, &cb_msg);
}{...}
break;...
case OBEX_TL_DATA_EVT:
assert(p_ccb != NULL);
if (p_ccb->callback) {
cb_msg.data.pkt = msg->data.p_buf;
p_ccb->callback(p_ccb->allocated, OBEX_DATA_EVT, &cb_msg);
}{...}
else {
osi_free(msg->data.p_buf);
}{...}
break;...
case OBEX_TL_CONN_INCOME_EVT:
assert(p_ccb == NULL);
p_scb = obex_find_scb_by_tl_hdl(tl, msg->conn_income.svr_hdl);
if (p_scb == NULL) {
obex_cb.tl_ops[tl]->disconnect(tl_hdl);
break;
}{...}
if ((p_ccb = obex_allocate_ccb()) == NULL) {
obex_cb.tl_ops[tl]->disconnect(tl_hdl);
break;
}{...}
p_ccb->tl = tl;
p_ccb->tl_hdl = tl_hdl;
p_ccb->role = OBEX_ROLE_SERVER;
p_ccb->tl_peer_mtu = msg->conn_income.peer_mtu;
p_ccb->tl_our_mtu = msg->conn_income.our_mtu;
if (!check_conn_mtu_valid(p_ccb, FALSE)) {
break;
}{...}
p_ccb->state = OBEX_STATE_OPENED;
p_ccb->callback = p_scb->callback;
if (p_ccb->callback) {
cb_msg.conn_income.svr_handle = p_scb->allocated << 8;
cb_msg.conn_income.peer_mtu = msg->conn_income.peer_mtu;
cb_msg.conn_income.our_mtu = msg->conn_income.our_mtu;
p_ccb->callback(p_ccb->allocated, OBEX_CONN_INCOME_EVT, &cb_msg);
}{...}
break;...
default:
OBEX_TRACE_ERROR("Unknown OBEX transport event: 0x%x\n", evt);
break;...
}{...}
}{...}
void obex_tl_l2cap_callback(tOBEX_TL_EVT evt, tOBEX_TL_MSG *msg)
{
obex_tl_evt_handler(OBEX_OVER_L2CAP, evt, msg);
}{...}
/* ... */
#endif