?? ag_servicerecord.c
字號:
#include "ag_private.h"
#include "ag.h"
#include <message.h>
#include <sdp_parse.h>
#include <stdlib.h>
#include <string.h>
/*
This structure defines the service record for the Audio Gateway;
it contains a blank space for the RFCOMM server channel since this
will be filled in at run time.
Note that attrIds are specified as being 16 bit ints.
*/
static const uint8 serviceRecord[] =
{
/* Service class ID list */
0x09,0x00,0x01, /* AttrID , ServiceClassIDList */
0x35,0x06, /* 6 bytes in total DataElSeq */
0x19,0x00,0x00,/* 2 byte UUID, Service class = Voice gateway */
0x19,0x12,0x03,/* 2 byte UUID Service class = GenericAudio */
/* protocol descriptor list */
0x09,0x00,0x04,/* AttrId ProtocolDescriptorList */
0x35,0x0c, /* 12 bytes in total DataElSeq */
0x35,0x03, /*3 bytes in DataElSeq */
0x19, 0x01,0x00,/* 2 byte UUID, Protocol = L2CAP */
0x35,0x05, /* 5 bytes in DataElSeq */
0x19, 0x00, 0x03, /* 1 byte UUID Protocol = RFCOMM */
0x08, 0x00, /* 1 byte UINT - server channel template value 0 - to be filled in by app */
/* profile descriptor list */
0x09,0x00,0x09, /* AttrId, ProfileDescriptorList */
0x35,0x08, /* 8 bytes in total DataElSeq */
0x35,0x06, /* 6 bytes in total DataElSeq */
0x19, 0x00,0x00, /* 2 byte UUID, Service class = Voice gateway */
0x09, 0x01,0x00, /* 2 byte uint, version = 100 */
/* service name */
0x09, 0x01, 0x00, /* AttrId - Service Name */
0x25, 0x0D, /* 13 byte string */
'V','o','i','c','e',' ','G','a','t','e','w','a','y'
};
static const uint8 handsFreeExtra[] =
{
/* Network */
0x09, 0x03, 0x01, /* AttrID - Network */
0x08, 0x00, /* 1 byte UINT - GSM like */
/* Supported Features (init to profile defaults) */
0x09, 0x03, 0x11, /* AttrId - Supported Features */
0x09, 0x00, 0x09 /* 2 byte UINT - Supported features */
/* 3 way calls - 1 (LSB) */
/* EC and/or NR fn - 0 */
/* Voice recognition fn - 0 */
/* In-band ring tone - 1 */
/* Attach phone num to tag - 0 */
};
/*
customizeServiceRecord
Fill in the profile specific fields in the service record
*/
static uint16 customizeServiceRecord(uint16 *len, uint8 **s_ptr, ag_profile_role_t dev_type)
{
uint8_t *ptr;
uint8_t *endptr;
/* Set the ptrs for sdp_parse function calls */
ptr = *s_ptr;
endptr = ptr + *len;
/* start by looking for the first UUID as this is the service class */
ptr = SdpFindElement(SDP_TYPE_UUID, ptr, endptr);
/* Check for null ptr access and return 0 to indicate something is wrong */
if (!ptr)
return 0;
/* write the service class and move on from that element */
if (dev_type == agHeadsetProfile)
{
SdpSetData(ptr, (uint32_t) 0x1112);
}
else if (dev_type == agHandsFreeProfile)
{
/* device must be hands free or we wouldn't get this far */
SdpSetData(ptr, (uint32_t) 0x111F);
}
else
{
return 0;
}
/* Skip the next UUIDs until we reach the one we're interested in */
for(;;)
{
/* Find the next UUID */
ptr = SdpFindElement(SDP_TYPE_UUID, ptr, endptr);
if (!ptr)
return 0;
/*
We're looking for the UUID after the RFCOMM UUID but unfortunately
it hasn't been set yet so we can't look for it directly
*/
if (SdpGetData(ptr) == SDP_UUID_RFCOMM)
{
ptr = SdpSkipElement(ptr);
ptr = SdpFindElement(SDP_TYPE_UUID, ptr, endptr);
if (ptr)
{
if (dev_type == agHeadsetProfile)
{
SdpSetData(ptr, (uint32_t) 0x1108);
}
else if (dev_type == agHandsFreeProfile)
{
SdpSetData(ptr, (uint32_t) 0x111E);
/*
For hands free profile also need to insert the supported features
the external driver passed in
*/
ptr = SdpFindElement(SDP_TYPE_STR, ptr, endptr);
ptr = SdpSkipElement(ptr);
ptr = SdpFindElement(SDP_TYPE_UINT, ptr, endptr);
ptr = SdpSkipElement(ptr);
if (!ptr)
return 0;
/* Set the network type */
SdpSetData(ptr, (uint32_t) (AGState.hfAgSupportedFeatures>>8));
/* Skip along */
ptr = SdpSkipElement(ptr);
/* Find the next uint that contains the supported features */
ptr = SdpFindElement(SDP_TYPE_UINT, ptr, endptr);
ptr = SdpSkipElement(ptr);
if (!ptr)
return 0;
/* Only the 5 LSBs of the LSW are valid so mask the rest off */
SdpSetData(ptr, (uint32_t) (AGState.hfAgSupportedFeatures & 0x001f));
}
else
{
return 0;
}
break ;
}
}
else
{
/* Skip to the next element and try our luck there */
ptr = SdpSkipElement(ptr);
}
}
return 1;
}
/*
agCreateServiceRecord
Create a copy of the service record; the Connection Manager will
fill in the RFCOMM channel for us since it knows about such things
we need to supply the length of the record also.
*/
uint8 *agCreateServiceRecord(uint16 *len, ag_profile_role_t dev_type)
{
uint8 *sr_ptr = 0;
uint16 sr_len=0;
uint16 return_flag = 1;
/*
Copy the relevant service record. Note that the hands free one record
has a number of extra fields so needs to be handled separately
*/
if (dev_type == agHeadsetProfile)
{
sr_len = sizeof(serviceRecord);
sr_ptr = (uint8 *)agAlloc(sr_len);
memcpy(sr_ptr,(void*) serviceRecord, sr_len);
*len = sr_len;
/* Fill in the headset specific fields into the service record */
if (!customizeServiceRecord(len, &sr_ptr, agHeadsetProfile))
return_flag = 0;
}
else if (dev_type == agHandsFreeProfile)
{
sr_len = sizeof(serviceRecord) + sizeof(handsFreeExtra);
sr_ptr = (uint8 *)agAlloc(sr_len);
memcpy(sr_ptr, (void*) serviceRecord, sizeof(serviceRecord));
memcpy(sr_ptr+sizeof(serviceRecord), (void*) handsFreeExtra, sizeof(handsFreeExtra));
*len = sr_len;
/* Fill in the hands free specific fields into the service record */
if (!customizeServiceRecord(len, &sr_ptr, agHandsFreeProfile))
return_flag = 0;
}
else
{
/* Unknown ervice type requested */
return_flag = 0;
}
if (!return_flag)
{
/* Failed to create the service record */
*len = 0;
free(sr_ptr);
return 0;
}
return sr_ptr;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -