|
From: Anders J. <and...@us...> - 2002-03-07 21:23:20
|
The following files were modified in apps/bluetooth/sdp_server:
Name Old version New version Comment
---- ----------- ----------- -------
sdp_parser.c 1.21 1.22=20=20=20=20=20=20=20=20=20=20=20=20
sdp_server.c 1.31 1.32=20=20=20=20=20=20=20=20=20=20=20=20
sdp_server.h 1.11 1.12=20=20=20=20=20=20=20=20=20=20=20=20
sdp_test.xml 1.1 Added
The accompanying log:
* Added FULL support for the continuation flag.
* Added sdp-test-database.
* Fixed several potential bugs in the sdp_server.
The diff of the modified file(s):
--- sdp_parser.c 27 Aug 2001 15:08:58 -0000 1.21
+++ sdp_parser.c 7 Mar 2002 21:23:19 -0000 1.22
@@ -346,6 +346,11 @@
cur_pos +=3D 2;
=20
cont_state_len =3D data[cur_pos++];
+ if (cont_state_len)
+ {
+ /* One byte for continuation data */
+ cur_pos +=3D 1;
+ }
=20
if (len < cur_pos)
{
@@ -363,10 +368,8 @@
=20=20=20
if (cont_state_len)
{
- cur_pos +=3D data[cur_pos];
-=20=20=20=20
D_MISC("Sending continuationstate packet");
- send_cont_state_search_rsp(cont_state_len, data + cur_pos, max_rec_cnt=
,db);
+ send_cont_state_search_rsp(data[cur_pos - 1], db);
}
else
{
@@ -485,8 +488,8 @@
if (cont_state_len)
{
D_MISC("Sending continuationstate packet");
- send_cont_state_attr_rsp(cont_state_len, data + cur_pos, max_attr_cnt,
- db);
+ send_cont_state_attr_rsp(data[cur_pos - 1], max_attr_cnt,
+ db, SDP_SERVICEATTR_REQ);
}
else
{
@@ -671,8 +674,8 @@
if (cont_state_len)
{
D_MISC("Sending continuationstate packet");
- send_cont_state_attr_rsp(cont_state_len, data + cur_pos, max_attr_cnt,
- db);
+ send_cont_state_attr_rsp(data[cur_pos - 1], max_attr_cnt,
+ db, SDP_SERVICESEARCHATTR_REQ);
}
else
{
--- sdp_server.c 19 Nov 2001 08:43:02 -0000 1.31
+++ sdp_server.c 7 Mar 2002 21:23:19 -0000 1.32
@@ -70,7 +70,6 @@
=20
/* Debug for the get record handle functions */
#define SDP_DEBUG_GET_RECORD_HDL 0
-
/* Debug all malloc and free commands */
#define SDP_DEBUG_MEM 0
=20
@@ -154,7 +153,7 @@
=20
int set_cont_state_attr(unsigned char *pkt, int len, int max_attr_len);
=20
-int set_cont_state_search(unsigned char *pkt, unsigned int len, unsigned i=
nt max_rec_cnt);
+int set_cont_state_search(unsigned char *pkt, unsigned int len);
=20
static int xml_fd;
static int parse_err;
@@ -1362,8 +1361,8 @@
int rsp_pkt_len;
unsigned int *rec_hdl_list;
unsigned int rec_hdl_cnt =3D 0;
- unsigned int max_rec_cnt;
- int i;
+ unsigned int rec_to_send =3D 0;
+ int i, j =3D 0;
=20
rec_hdl_list =3D get_all_rec_hdl(db_hdl->service_class_list, db_hdl->ser=
vice_class_cnt);
=20
@@ -1382,33 +1381,32 @@
=20
D_MISC("Found %d rec handles in database\n", rec_hdl_cnt);
=20
+ /* We shouldn't return more than max_rec_cnt */
+ if (rec_hdl_cnt > db_hdl->max_rec_cnt)=20
+ {
+ D_REC("Only send %d out of %d record handles\n", db_hdl->max_rec_cnt, =
rec_hdl_cnt);
+ rec_hdl_cnt =3D db_hdl->max_rec_cnt;
+ }
+
/* Calculate how many records we can fit into response */
/* SdpHdrSize[5] + TotSrvCnt[2] + CurSrvRevCnt[2] + possibl ContState[2]=
=20
=3D> 11 bytes. Each rec hdl is 4 bytes */
=20
- max_rec_cnt =3D MIN(db_hdl->max_rec_cnt, (db_hdl->db.l2cap_mtu - 11)/4);
-
- if (rec_hdl_cnt > max_rec_cnt)=20
- {
- D_REC("Only send %d out of %d record handles\n", max_rec_cnt, rec_hdl_=
cnt);
- rec_hdl_cnt =3D max_rec_cnt;
- }
+ rec_to_send =3D MIN(rec_hdl_cnt, (db_hdl->db.l2cap_mtu - 11) / 4);
=20=20=20
rsp_pkt_len =3D SDP_HDR_SIZE;=20=20
=20=20=20
- /* Set the total service record count */
+ /* Set the total service record count which are going to be sent */
rsp_pkt[rsp_pkt_len++] =3D SHORT2CHAR_MS(rec_hdl_cnt);
rsp_pkt[rsp_pkt_len++] =3D SHORT2CHAR_LS(rec_hdl_cnt);
=20=20=20
- /* fixme -- total/current should probably differ sometimes... */
-=20=20
- /* Set the current service record count */
- rsp_pkt[rsp_pkt_len++] =3D SHORT2CHAR_MS(rec_hdl_cnt);
- rsp_pkt[rsp_pkt_len++] =3D SHORT2CHAR_LS(rec_hdl_cnt);
+ /* Set the current service record count which can be transmitted in one =
packet */
+ rsp_pkt[rsp_pkt_len++] =3D SHORT2CHAR_MS(rec_to_send);
+ rsp_pkt[rsp_pkt_len++] =3D SHORT2CHAR_LS(rec_to_send);
=20=20=20
if (rec_hdl_list)
{
- for (i =3D 0; i < rec_hdl_cnt; i++)
+ for (i =3D 0; i < rec_to_send; i++)
{
rsp_pkt[rsp_pkt_len++] =3D (rec_hdl_list[i] >> 24) & 0xff;
rsp_pkt[rsp_pkt_len++] =3D (rec_hdl_list[i] >> 16) & 0xff;
@@ -1417,24 +1415,42 @@
}
}
=20=20=20
- set_sdp_hdr(rsp_pkt, SDP_SERVICESEARCH_RSP, db_hdl->db.trans_id,
- rsp_pkt_len - SDP_HDR_SIZE);
-
- D_REC("l2cap_mtu:%d, mrc:%d, db->mrc:%d\n", db_hdl->db.l2cap_mtu, max_re=
c_cnt, db_hdl->max_rec_cnt);
-
- /* If Max Service Record Count is set to a value less than the number of
- available records in database we should not set cont state */
+ /* Check if we should set continuation flag, if true save the rest of
+ our found records */
+ if(rec_hdl_cnt > rec_to_send)
+ {
+ cont_state_buf =3D malloc(sizeof(cont_state_struct) + ((rec_hdl_cnt -=
rec_to_send) * 4));
+ D_MEM("---> malloc%d %ld bytes at 0x%8p", malloc_dbg++, sizeof(cont_s=
tate_struct) +=20
+ ((rec_hdl_cnt - rec_to_send) * 4), cont_state_buf);
=20
- /* set_cont_state_search searches rsp_pkt for currently set rec cnt=20
- and we compare that with max_rec_cnt. If current is larger than
- max rec cnt, we set continuation state and change headers in rsp
- packet. If not we simply put a 0 in the end to indicate no cont=20
- state */
+ if(cont_state_buf)=20
+ {
+ cont_state_buf->id =3D 0;
+ cont_state_buf->pdu =3D SDP_SERVICESEARCH_REQ;
+ cont_state_buf->cur_pos =3D 0;
+ cont_state_buf->total_len =3D rec_hdl_cnt * 4;
=20=20=20
- /* fixme -- as of today we can only handle continuation state for=20
- 1 client at a time */
+ for(i =3D rec_to_send ; i < rec_hdl_cnt ; i++)
+ {
+ cont_state_buf->data[j++] =3D (rec_hdl_list[i] >> 24) & 0xff;
+ cont_state_buf->data[j++] =3D (rec_hdl_list[i] >> 16) & 0xff;
+ cont_state_buf->data[j++] =3D (rec_hdl_list[i] >> 8) & 0xff;
+ cont_state_buf->data[j++] =3D rec_hdl_list[i] & 0xff;
+ }
=20
- rsp_pkt_len =3D set_cont_state_search(rsp_pkt, rsp_pkt_len, max_rec_cnt);
+ cont_state_buf->len =3D j;
+ rsp_pkt[rsp_pkt_len++] =3D 0x01;
+ rsp_pkt[rsp_pkt_len++] =3D cont_state_buf->id;
+ }
+ else
+ {
+ set_err(SDP_INSUFFICIENT_RESOURCES);
+ }
+ }=20
+ else=20
+ {
+ rsp_pkt[rsp_pkt_len++] =3D 0x00;
+ }=20=20=20=20=20=20=20=20
=20
if (is_err())
{
@@ -1442,6 +1458,12 @@
return;
}
=20=20=20
+ set_sdp_hdr(rsp_pkt, SDP_SERVICESEARCH_RSP, db_hdl->db.trans_id,
+ rsp_pkt_len - SDP_HDR_SIZE);
+
+ D_REC("l2cap_mtu:%d, Records to send:%d, Total max records to return:%d\=
n",=20
+ db_hdl->db.l2cap_mtu, rec_to_send, db_hdl->max_rec_cnt);
+=20=20
write2stack(db_hdl->db.sdp_con_id, rsp_pkt, rsp_pkt_len);=20
}
=20
@@ -1452,6 +1474,11 @@
int rsp_pkt_len, i, des_len_pos;
unsigned char *tmp_ptr;
unsigned int max_attr_byte_cnt;
+ unsigned int cont_bytes =3D 1;
+ unsigned int bytes_to_send =3D 0;
+
+ max_attr_byte_cnt =3D MIN(db_hdl->max_attr_byte_cnt, db_hdl->db.l2cap_mt=
u - 9);
+ /* 9 comes from SDP_HDR_SIZE + attr byte nt field + 2 bytes for cont sta=
te */
=20=20=20=20=20
/* Skip the sdp header and the attribute byte count field */
rsp_pkt_len =3D SDP_HDR_SIZE + 2;
@@ -1460,6 +1487,8 @@
des_len_pos =3D rsp_pkt_len;
rsp_pkt_len++;
=20
+ bytes_to_send =3D rsp_pkt_len - SDP_HDR_SIZE - 2;
+
for (i =3D 0; i < db_hdl->attr_cnt; i++)
{
if ((db_hdl->attr_list[i] & 0xffff) ^ (db_hdl->attr_list[i] >> 16))
@@ -1486,32 +1515,58 @@
}
}
=20
+ if((rsp_pkt_len - SDP_HDR_SIZE - 2) > max_attr_byte_cnt)
+ {
+ bytes_to_send =3D max_attr_byte_cnt;
+ cont_state_buf =3D malloc(sizeof(cont_state_struct) + (rsp_pkt_len - S=
DP_HDR_SIZE - 2 - bytes_to_send));
+ D_MEM("---> malloc%d %ld bytes at 0x%8p", malloc_dbg++, sizeof(cont_st=
ate_struct) +=20
+ rsp_pkt_len - SDP_HDR_SIZE - 2 - bytes_to_send, cont_state_buf);
+=20=20=20=20
+ if(cont_state_buf)=20
+ {
+ memcpy(cont_state_buf->data, &rsp_pkt[bytes_to_send + SDP_HDR_SIZE +=
2],=20
+ rsp_pkt_len - SDP_HDR_SIZE - 2 - bytes_to_send);
+ cont_state_buf->id =3D 0;
+ cont_state_buf->len =3D rsp_pkt_len - SDP_HDR_SIZE - 2 - bytes_to_se=
nd;
+ cont_state_buf->cur_pos =3D 0;
+ cont_state_buf->total_len =3D rsp_pkt_len - SDP_HDR_SIZE - 2;
+ cont_state_buf->pdu =3D SDP_SERVICEATTR_REQ;
+ cont_bytes =3D 2;
+ rsp_pkt[bytes_to_send + SDP_HDR_SIZE + 2] =3D 0x01;
+ rsp_pkt[bytes_to_send + SDP_HDR_SIZE + 2 + 1] =3D 0x00;
+ }
+ else
+ {
+ set_err(SDP_INSUFFICIENT_RESOURCES);
+ }
+ }=20
+ else
+ {
+ bytes_to_send =3D rsp_pkt_len - SDP_HDR_SIZE - 2;
+ rsp_pkt[bytes_to_send + SDP_HDR_SIZE + 2] =3D 0x00;
+ }
+
/* Set the attribute byte count to packet length minus sdp pdu header si=
ze
minus attribute byte count field length, minus continuation field len=
gth*/
- rsp_pkt[SDP_HDR_SIZE] =3D SHORT2CHAR_MS(rsp_pkt_len - SDP_HDR_SIZE - 2=
);
- rsp_pkt[SDP_HDR_SIZE+1] =3D SHORT2CHAR_LS(rsp_pkt_len - SDP_HDR_SIZE - 2=
);
+ rsp_pkt[SDP_HDR_SIZE] =3D SHORT2CHAR_MS(bytes_to_send);
+ rsp_pkt[SDP_HDR_SIZE+1] =3D SHORT2CHAR_LS(bytes_to_send);
=20
/* The length of the attribute list is the length of the attribute byte
count minus the size of the data element sequence header */
rsp_pkt[des_len_pos] =3D rsp_pkt_len - SDP_HDR_SIZE - 2 - 2;
=20=20=20
set_sdp_hdr(rsp_pkt, SDP_SERVICEATTR_RSP, db_hdl->db.trans_id,
- rsp_pkt_len - SDP_HDR_SIZE);
-
- max_attr_byte_cnt =3D MIN(db_hdl->max_attr_byte_cnt, db_hdl->db.l2cap_mt=
u - 9);
- /* 9 comes from SDP_HDR_SIZE + attr byte nt field + 2 bytes for cont sta=
te */
+ bytes_to_send + 2 + cont_bytes);
=20
D_REC("l2cap_mtu:%d, mabc:%d, db->mabc:%d\n", db_hdl->db.l2cap_mtu, max_=
attr_byte_cnt, db_hdl->max_attr_byte_cnt);
=20=20=20=20
- rsp_pkt_len =3D set_cont_state_attr(rsp_pkt, rsp_pkt_len, max_attr_byte_=
cnt);
-
if (is_err())
{
send_error_rsp(&db_hdl->db, get_err());
return;
}
=20=20=20
- write2stack(db_hdl->db.sdp_con_id, rsp_pkt, rsp_pkt_len);=20
+ write2stack(db_hdl->db.sdp_con_id, rsp_pkt, bytes_to_send + 2 + cont_byt=
es + SDP_HDR_SIZE);=20
}
=20
void
@@ -1519,11 +1574,17 @@
{
unsigned char *tmp_ptr;
unsigned int *rec_hdl_list;
- unsigned int rec_hdl_cnt;
+ unsigned int rec_hdl_cnt =3D 0;
unsigned char rsp_pkt[1024];
unsigned int max_attr_byte_cnt;
+ unsigned int bytes_to_send;
+ unsigned int cont_bytes =3D 1;
+
int rsp_pkt_len =3D 0, tmp_len, des_len_pos, i, j =3D 0;
=20
+ max_attr_byte_cnt =3D MIN(db_hdl->max_attr_byte_cnt, db_hdl->db.l2cap_mt=
u - 9);
+ /* 9 comes from SDP_HDR_SIZE + attr byte nt field + 2 bytes for cont sta=
te */
+
rec_hdl_list =3D get_all_rec_hdl(db_hdl->service_class_list, db_hdl->ser=
vice_class_cnt);
=20
D_REC("Got a record handle list");
@@ -1552,6 +1613,8 @@
des_len_pos =3D rsp_pkt_len;
rsp_pkt_len +=3D 2;
=20
+ bytes_to_send =3D rsp_pkt_len - SDP_HDR_SIZE - 2;
+
for (j =3D 0; j < rec_hdl_cnt; j++)
{
tmp_len =3D 2;
@@ -1590,173 +1653,102 @@
}
}
=20
- /* Set the attribute byte count to packet length minus sdp pdu header si=
ze
- minus attribute byte count field length */
- rsp_pkt[SDP_HDR_SIZE] =3D SHORT2CHAR_MS(rsp_pkt_len - SDP_HDR_SIZE - 2=
);
- rsp_pkt[SDP_HDR_SIZE+1] =3D SHORT2CHAR_LS(rsp_pkt_len - SDP_HDR_SIZE - 2=
);
-
- /* The length of the attribute list is the same as the packet length min=
us
- the packet header length minus the attibute byte count filed minus the
- data element sequence header*/
- rsp_pkt[des_len_pos] =3D SHORT2CHAR_MS(rsp_pkt_len - SDP_HDR_SIZE - =
2 - 3);
- rsp_pkt[des_len_pos + 1] =3D SHORT2CHAR_LS(rsp_pkt_len - SDP_HDR_SIZE - =
2 - 3);
-
- set_sdp_hdr(rsp_pkt, SDP_SERVICESEARCHATTR_RSP, db_hdl->db.trans_id,
- rsp_pkt_len - SDP_HDR_SIZE);
-
- max_attr_byte_cnt =3D MIN(db_hdl->max_attr_byte_cnt, db_hdl->db.l2cap_mt=
u - 9);
- /* 9 comes from SDP_HDR_SIZE + attr byte nt field + 2 bytes for cont sta=
te */
-
- D_REC("l2cap_mtu:%d, mabc:%d, db->mabc:%d\n", db_hdl->db.l2cap_mtu, max_=
attr_byte_cnt, db_hdl->max_attr_byte_cnt);
-=20=20
- rsp_pkt_len =3D set_cont_state_attr(rsp_pkt, rsp_pkt_len, max_attr_byte_=
cnt);
-=20=20
- if (is_err())
- {
- send_error_rsp(&db_hdl->db, get_err());
- return;
- }
-=20=20
- /* FIXME: Add features to handle continuation state packets */
- write2stack(db_hdl->db.sdp_con_id, rsp_pkt, rsp_pkt_len);=20
-}
-
-int
-set_cont_state_search(unsigned char *pkt, unsigned int len, unsigned int m=
ax_rec_cnt)
+ /* Did all data fit into one respone? If false we should copy the remain=
ing
+ data to the cont.buffer and set the continuationflag */
+ if((rsp_pkt_len - SDP_HDR_SIZE - 2) > max_attr_byte_cnt)
{
- int cur_rec_cnt;
- int cnt_len;
-
- cur_rec_cnt =3D CHAR2INT16(pkt[SDP_HDR_SIZE+2], pkt[SDP_HDR_SIZE+3]);
+ bytes_to_send =3D max_attr_byte_cnt;
+ cont_state_buf =3D malloc(sizeof(cont_state_struct) + (rsp_pkt_len - S=
DP_HDR_SIZE - 2 - bytes_to_send));
+ D_MEM("---> malloc%d %ld bytes at 0x%8p", malloc_dbg++, sizeof(cont_st=
ate_struct) +=20
+ rsp_pkt_len - SDP_HDR_SIZE - 2 - bytes_to_send, cont_state_buf);
=20
- if (cur_rec_cnt > max_rec_cnt)
+ if(cont_state_buf)=20
{
- S_FNC("Setting cont state, cur_rec_cnt:%d, max_rec_cnt:%d",
- cur_rec_cnt, max_rec_cnt);
-
- pkt[SDP_HDR_SIZE] =3D SHORT2CHAR_MS(max_rec_cnt);
- pkt[SDP_HDR_SIZE+1] =3D SHORT2CHAR_LS(max_rec_cnt);
-
- pkt[SDP_HDR_SIZE+2] =3D SHORT2CHAR_MS(max_rec_cnt);
- pkt[SDP_HDR_SIZE+3] =3D SHORT2CHAR_LS(max_rec_cnt);
-=20=20=20=20
- /* There are cnt_len byte too much to fit the data in one packet */
- cnt_len =3D (cur_rec_cnt - max_rec_cnt) * 4;
-=20=20=20=20
- /* The packet can't be longer than this, excluding the continuation st=
ate
- bytes */
- len -=3D cnt_len;
-=20=20=20=20
- cont_state_buf =3D malloc(sizeof(cont_state_struct) + cnt_len);
- D_MEM("---> malloc%d %ld bytes at 0x%8p", malloc_dbg++, sizeof(cont_st=
ate_struct) + cnt_len, cont_state_buf);
-
- if (!cont_state_buf)
+ memcpy(cont_state_buf->data, &rsp_pkt[bytes_to_send + SDP_HDR_SIZE +=
2],=20
+ rsp_pkt_len - SDP_HDR_SIZE - 2 - bytes_to_send);
+ cont_state_buf->id =3D 0;
+ cont_state_buf->len =3D rsp_pkt_len - SDP_HDR_SIZE - 2 - bytes_to_se=
nd;
+ cont_state_buf->cur_pos =3D 0;
+ cont_state_buf->total_len =3D rsp_pkt_len - SDP_HDR_SIZE - 2;
+ cont_state_buf->pdu =3D SDP_SERVICESEARCHATTR_REQ;
+ cont_bytes =3D 2;
+ rsp_pkt[bytes_to_send + SDP_HDR_SIZE + 2] =3D 0x01;
+ rsp_pkt[bytes_to_send + SDP_HDR_SIZE + 2 + 1] =3D 0x00;
+ }
+ else
{
set_err(SDP_INSUFFICIENT_RESOURCES);
- return 0;
}
-=20=20=20=20
- cont_state_buf->pdu =3D pkt[SDP_HDR_TYPE];
- D_MISC("PDU: 0x%02x", cont_state_buf->pdu);
-=20=20=20=20
- cont_state_buf->len =3D cnt_len;
- memcpy(cont_state_buf->data, pkt + len, cnt_len);
-=20=20=20=20
- len =3D SDP_HDR_SIZE + 2 + 2 + (max_rec_cnt * 4);
-
- pkt[len++] =3D 1;
- pkt[len++] =3D 0;
}
else
{
- D_MISC("No continuation state set\n");
- pkt[len++] =3D 0;
- }
-=20=20
-=20=20
- /* Change the length field */
- pkt[SDP_HDR_LENGTH_MS] =3D SHORT2CHAR_MS(len - SDP_HDR_SIZE);
- pkt[SDP_HDR_LENGTH_LS] =3D SHORT2CHAR_LS(len - SDP_HDR_SIZE);
-
- return len;
+ bytes_to_send =3D rsp_pkt_len - SDP_HDR_SIZE - 2;
+ rsp_pkt[bytes_to_send + SDP_HDR_SIZE + 2] =3D 0x00;
}
=20
-/* FIXME: This function only handles continuation state from one query yet=
*/
-
-int
-set_cont_state_attr(unsigned char *pkt, int len, int max_attr_len)
-{
- int cur_attr_cnt;
- int cont_len;
=20
- cur_attr_cnt =3D CHAR2INT16(pkt[SDP_HDR_SIZE], pkt[SDP_HDR_SIZE+1]);
-
- S_FNC("len %d, max_attr_len %d, cur_attr_cnt %d", len, max_attr_len, cur=
_attr_cnt);
-
- PRINT_DATA(__FUNCTION__, pkt, len);
-
- if (max_attr_len < cur_attr_cnt)
- {
- S_FNC("max_attr_len:%d, cur_attr_cnt:%d and packet length:%d", max_att=
r_len, cur_attr_cnt, len);
-
- /* There are cont_len byte to much to fit the data in one packet */
- cont_len =3D cur_attr_cnt - max_attr_len;
-
- /* The packet can't be longer than this, excluding the continuation st=
ate
- bytes */
- len -=3D cont_len;
-
- cont_state_buf =3D malloc(sizeof(cont_state_struct) + cont_len);
- D_MEM("---> malloc%d %ld bytes at 0x%8p", malloc_dbg++, sizeof(cont_st=
ate_struct) + cont_len , cont_state_buf);
-
- if (!cont_state_buf)
- {
- set_err(SDP_INSUFFICIENT_RESOURCES);
- return 0;
- }
+ /* Set the attribute byte count to packet length minus sdp pdu header si=
ze
+ minus attribute byte count field length which is bytes_to_send */
+ rsp_pkt[SDP_HDR_SIZE] =3D SHORT2CHAR_MS(bytes_to_send);
+ rsp_pkt[SDP_HDR_SIZE+1] =3D SHORT2CHAR_LS(bytes_to_send);
=20=20=20=20=20
- cont_state_buf->pdu =3D pkt[SDP_HDR_TYPE];
- D_MISC("PDU: 0x%02x", cont_state_buf->pdu);
+ /* bytes_to_send is the total number of bytes in the attribute ID list a=
nd
+ the size of the data element sequence is that size - 3 bytes for the
+ header of the DES */
+ rsp_pkt[des_len_pos] =3D SHORT2CHAR_MS(rsp_pkt_len - SDP_HDR_SIZE - =
5);
+ rsp_pkt[des_len_pos + 1] =3D SHORT2CHAR_LS(rsp_pkt_len - SDP_HDR_SIZE - =
5);
=20
- cont_state_buf->len =3D cont_len;
- memcpy(cont_state_buf->data, pkt + len, cont_len);
+ /* Parameterlength for the PDU is total number of bytes in our Attribute=
IDList
+ + 2 bytes for MaximumAttributeCount + the continuationflag */
+ set_sdp_hdr(rsp_pkt, SDP_SERVICESEARCHATTR_RSP, db_hdl->db.trans_id,
+ bytes_to_send + 2 + cont_bytes);
=20
- pkt[SDP_HDR_SIZE] =3D SHORT2CHAR_MS(max_attr_len);
- pkt[SDP_HDR_SIZE+1] =3D SHORT2CHAR_LS(max_attr_len);
+ D_REC("l2cap_mtu:%d, mabc:%d, db->mabc:%d\n", db_hdl->db.l2cap_mtu, max_=
attr_byte_cnt, db_hdl->max_attr_byte_cnt);
=20=20=20=20=20
- pkt[len++] =3D 1;
- pkt[len++] =3D 0;
- }
- else
+ if (is_err())
{
- S_FNC("No continuation State set");
- pkt[len++] =3D 0;
+ send_error_rsp(&db_hdl->db, get_err());
+ return;
}
=20=20=20
- /* Change the length field */
-
- S_FNC("Changing length field");
- pkt[SDP_HDR_LENGTH_MS] =3D SHORT2CHAR_MS(len - SDP_HDR_SIZE);
- pkt[SDP_HDR_LENGTH_LS] =3D SHORT2CHAR_LS(len - SDP_HDR_SIZE);
-
- return len;
+ /* Length is bytes_to_send + 2 bytes for MaximumAttributeBytesCount + co=
nt. bytes + header size for the PDU */
+ write2stack(db_hdl->db.sdp_con_id, rsp_pkt, bytes_to_send + 2 + cont_byt=
es + SDP_HDR_SIZE);=20
}
=20
void
-send_cont_state_search_rsp(int len, unsigned char *info, int max_rec_cnt,
+send_cont_state_search_rsp(unsigned char cont_id,
database_query_struct *db)
{
unsigned char *send_buf;
int send_len;
+ int total_record_cnt;
+ int records_to_send;
+ int prev_send;
+ int cont_bytes =3D 1;
=20=20=20
- if (!cont_state_buf) {
+ if (!cont_state_buf ||=20
+ (cont_state_buf->pdu !=3D SDP_SERVICESEARCH_REQ) ||=20
+ (cont_state_buf->id !=3D cont_id))=20
+ {
send_error_rsp(db, SDP_INVALID_CONTINUATION_STATE);
}
- else if ((max_rec_cnt * 4) >=3D cont_state_buf->len)
+
+ total_record_cnt =3D cont_state_buf->total_len / 4;
+ prev_send =3D ((cont_state_buf->total_len - cont_state_buf->len) + cont_=
state_buf->cur_pos) / 4;
+
+ records_to_send =3D MIN(total_record_cnt - prev_send, (db->l2cap_mtu - 1=
1) / 4);
+=20=20
+ if((records_to_send + prev_send) !=3D total_record_cnt)
{
+ cont_bytes =3D 2;
+ }
+=20=20
+ /* Is it possible for the client to change its max_record_count in a=20
+ subsequent request?? */
+
/* Allocate space for the SDP header, the attribute byte count field,
the attributes and the continuation state field */
- send_len =3D SDP_HDR_SIZE + 2 + 2 + cont_state_buf->len + 1;
+ send_len =3D SDP_HDR_SIZE + 2 + 2 + records_to_send * 4 + cont_bytes;
=20
send_buf =3D malloc(send_len);
D_MEM("---> malloc%d %d bytes at 0x%8p", malloc_dbg++, send_len, send_=
buf);
@@ -1766,56 +1758,90 @@
return;
}
=20
- set_sdp_hdr(send_buf, cont_state_buf->pdu, db->trans_id, send_len - SD=
P_HDR_SIZE);
+ set_sdp_hdr(send_buf, SDP_SERVICESEARCH_RSP, db->trans_id, send_len - SD=
P_HDR_SIZE);
=20
- /* Set the attribute byte count field */
- send_buf[SDP_HDR_SIZE] =3D SHORT2CHAR_MS(cont_state_buf->len / 4);
- send_buf[SDP_HDR_SIZE+1] =3D SHORT2CHAR_LS(cont_state_buf->len / 4);
+ /* Set the total attribute byte count field */
+ send_buf[SDP_HDR_SIZE] =3D SHORT2CHAR_MS(total_record_cnt);
+ send_buf[SDP_HDR_SIZE+1] =3D SHORT2CHAR_LS(total_record_cnt);
=20
/* Set the attribute byte count field */
- send_buf[SDP_HDR_SIZE+2] =3D SHORT2CHAR_MS(cont_state_buf->len / 4);
- send_buf[SDP_HDR_SIZE+3] =3D SHORT2CHAR_LS(cont_state_buf->len / 4);
+ send_buf[SDP_HDR_SIZE+2] =3D SHORT2CHAR_MS(records_to_send);
+ send_buf[SDP_HDR_SIZE+3] =3D SHORT2CHAR_LS(records_to_send);
=20
- memcpy(send_buf + SDP_HDR_SIZE + 2 + 2, cont_state_buf->data, cont_sta=
te_buf->len);
+ memcpy(send_buf + SDP_HDR_SIZE + 2 + 2, &cont_state_buf->data[cont_state=
_buf->cur_pos], records_to_send * 4);
=20
+ if(cont_bytes =3D=3D 2)=20
+ {
+ send_buf[send_len - 2] =3D 1;
+ send_buf[send_len - 1] =3D ++cont_state_buf->id;
+ cont_state_buf->cur_pos +=3D records_to_send * 4;
+ }
+ else
+ {
send_buf[send_len - 1] =3D 0;
+ free(cont_state_buf);
+ D_MEM("<--- free%d 0x%8p", --malloc_dbg, cont_state_buf);
+ cont_state_buf =3D NULL;
+ }
=20
/* Send the whole buffer */
write2stack(db->sdp_con_id, send_buf, send_len);
=20
D_MEM("<--- free%d 0x%8p", --malloc_dbg, send_buf);
free(send_buf);
-
- D_MEM("<--- free%d 0x%8p", --malloc_dbg, cont_state_buf);
- free(cont_state_buf);
- cont_state_buf =3D NULL;
- }
- else
- {
- /* Write as much as possible */
-
- /* FIXME: Have to implement this too... */
-
- send_error_rsp(db, SDP_INVALID_SDP_VERSION);
- }
}
=20
void
-send_cont_state_attr_rsp(int len, unsigned char *info, int max_attr_cnt,
- database_query_struct *db)
+send_cont_state_attr_rsp(unsigned char cont_id, int max_attr_cnt,
+ database_query_struct *db, unsigned char pdu)
{
unsigned char *send_buf;
int send_len;
+ int total_cnt;
+ int bytes_to_send;
+ int prev_send;
+ int cont_bytes =3D 2;
+ unsigned char reply_pdu;
=20=20=20
- if (!cont_state_buf) {
+ if (!cont_state_buf ||=20
+ (cont_state_buf->pdu !=3D pdu) ||=20
+ (cont_state_buf->id !=3D cont_id))=20
+ {
send_error_rsp(db, SDP_INVALID_CONTINUATION_STATE);
}
- else if (max_attr_cnt >=3D cont_state_buf->len)
+
+ if(cont_state_buf->pdu =3D=3D SDP_SERVICESEARCHATTR_REQ)=20
+ {
+ reply_pdu =3D SDP_SERVICESEARCHATTR_RSP;
+ }
+ else
{
+ reply_pdu =3D SDP_SERVICEATTR_RSP;
+ }
+=20=20
+
+ total_cnt =3D cont_state_buf->total_len;
+ prev_send =3D (total_cnt - cont_state_buf->len) + cont_state_buf->cur_po=
s;
+=20=20
+ bytes_to_send =3D MIN(total_cnt - prev_send, max_attr_cnt);
+
+ /* Calculate how much data we can fit in one response */
+ /* SdpHdrSize[5] + AttributeListCount[2] + possibl ContState[2]=20
+ =3D> 9 bytes. */
+
+ if((bytes_to_send + 9) > db->l2cap_mtu - 9)
+ {
+ bytes_to_send =3D db->l2cap_mtu - 9;
+ }
+
+ if(bytes_to_send + cont_state_buf->cur_pos =3D=3D cont_state_buf->len)
+ {
+ cont_bytes =3D 1;
+ }
+
/* Allocate space for the SDP header, the attribute byte count field,
the attributes and the continuation state field */
- send_len =3D SDP_HDR_SIZE + 2 + cont_state_buf->len + 1;
-
+ send_len =3D SDP_HDR_SIZE + 2 + bytes_to_send + cont_bytes;
send_buf =3D malloc(send_len);
D_MEM("---> malloc%d %d bytes at 0x%8p", malloc_dbg++, send_len, send_=
buf);
if (!send_buf)
@@ -1824,32 +1850,29 @@
return;
}
=20
- set_sdp_hdr(send_buf, cont_state_buf->pdu, db->trans_id, send_len - SD=
P_HDR_SIZE);
-
/* Set the attribute byte count field */
- send_buf[SDP_HDR_SIZE] =3D SHORT2CHAR_MS(cont_state_buf->len);
- send_buf[SDP_HDR_SIZE+1] =3D SHORT2CHAR_LS(cont_state_buf->len);
-
- memcpy(send_buf + SDP_HDR_SIZE + 2, cont_state_buf->data, cont_state_b=
uf->len);
-
- send_buf[send_len - 1] =3D 0;
-
- /* Send the whole buffer */
- write2stack(db->sdp_con_id, send_buf, send_len);
-
- D_MEM("<--- free%d 0x%8p", --malloc_dbg, send_buf);
- free(send_buf);
+ send_buf[SDP_HDR_SIZE] =3D SHORT2CHAR_MS(bytes_to_send);
+ send_buf[SDP_HDR_SIZE+1] =3D SHORT2CHAR_LS(bytes_to_send);
=20
+ memcpy(send_buf + SDP_HDR_SIZE + 2, &cont_state_buf->data[cont_state_buf=
->cur_pos], bytes_to_send);
+ cont_state_buf->cur_pos +=3D bytes_to_send;
+ if(cont_bytes =3D=3D 2)=20
+ {
+ send_buf[SDP_HDR_SIZE + 2 + bytes_to_send] =3D 0x01;
+ send_buf[SDP_HDR_SIZE + 2 + bytes_to_send + 1] =3D ++cont_state_buf->i=
d;
+ }
+ else
+ {
+ send_buf[SDP_HDR_SIZE + 2 + bytes_to_send] =3D 0x00;
D_MEM("<--- free%d 0x%8p", --malloc_dbg, cont_state_buf);
free(cont_state_buf);
cont_state_buf =3D NULL;
}
- else
- {
- /* Write as much as possible */
=20
- /* FIXME: Have to implement this too... */
+ set_sdp_hdr(send_buf, reply_pdu, db->trans_id, bytes_to_send + 2 + cont_=
bytes);
+ /* Send the whole buffer */
+ write2stack(db->sdp_con_id, send_buf, send_len);
=20
- send_error_rsp(db, SDP_INVALID_SDP_VERSION);
- }
+ D_MEM("<--- free%d 0x%8p", --malloc_dbg, send_buf);
+ free(send_buf);
}
--- sdp_server.h 14 Jun 2001 10:30:42 -0000 1.11
+++ sdp_server.h 7 Mar 2002 21:23:19 -0000 1.12
@@ -151,8 +151,11 @@
=20
typedef struct cont_state_struct
{
+ unsigned char id;
unsigned char pdu;
int len;
+ int cur_pos;
+ int total_len;
unsigned char data[0];
} cont_state_struct;
=20
@@ -162,11 +165,13 @@
void init_sdp_server(int fd);
void print_data(const char *message, const unsigned char *buf, int len);
void
-send_cont_state_search_rsp(int len, unsigned char *info, int max_rec_cnt,
+send_cont_state_search_rsp(unsigned char cont_id,
database_query_struct *db);
void
-send_cont_state_attr_rsp(int len, unsigned char *info, int max_attr_cnt,
- database_query_struct *db);
+send_cont_state_attr_rsp(unsigned char cont_id, int max_attr_cnt,
+ database_query_struct *db, unsigned char pdu);
+
+
unsigned int *get_more_rec_hdl(unsigned short servive_class, int fd);
void send_error_rsp(database_query_struct *db, unsigned short err_code);
=20
|