Beispiel #1
0
static void add_lang_attr(sdp_record_t *r)
{
        sdp_lang_attr_t base_lang;
        sdp_list_t *langs = 0;
        /* UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) */
        base_lang.code_ISO639 = (0x65 << 8) | 0x6e;
        base_lang.encoding = 106;
        base_lang.base_offset = SDP_PRIMARY_LANG_BASE;
        langs = sdp_list_append(0, &base_lang);
        sdp_set_lang_attr(r, langs);
        sdp_list_free(langs, 0);
}
Beispiel #2
0
int sdpreg_pan(struct btservice *svc)
{
	int		status = -1;
	sdpsvc_t	*svcRec;
	sdpdata_t	*attr;
	slist_t		*ptype = NULL;

	/*
	 ** First create a service record handle
	 */
	s_list_append_uint(&ptype, 0x800); 
	s_list_append_uint(&ptype, 0x806);
	svcRec = sdp_create_pan_svc(svc->profile->svc_class, ptype, 0x0000, 0x0005, 0x100);
	s_list_free(&ptype);
	if (svcRec == NULL)
		return -1;
	/* add language attribute */
	attr = sdp_set_lang_attr(svcRec);
	if (attr == NULL) {
		BTERROR("setLanguageBase failed");
		sdp_free_svc(svcRec);
		return -1;
	}
	status = sdp_add_lang(attr, 0, 0, 0);
	if (status) {
		sdp_free_svc(svcRec);
		return -1;
	}
	/* set informational attibutes */		
	status = sdp_set_info_attr(svcRec, svc->name, svc->prov, svc->desc);
	if (status != 0) {
		sdp_free_svc(svcRec);
		return -1;
	}
	status = sdp_register_service(srvHandle, svcRec);
	if (status != 0) {
		BTERROR("sdp_register_service failed");
		sdp_free_svc(svcRec);
		return -1;
	}
	svc->svcRec = svcRec;
	return 0;
}
int register_record(int descriptor_is_relative){


		// Connect to to local SDP-Servicer on localhost, to publish
		// the new service record.

		// Session will be established.
		sdp_session_t *session;

		session = sdp_connect ( BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY );

			if ( ! session )
			{

				//	LOGCAT:
				__android_log_print(ANDROID_LOG_DEBUG, TAG, "SDP: Connection to SDP failed.");

				return CODE_SDP_SESSION_FAILED;
			}

				//	LOGCAT:
				__android_log_print(ANDROID_LOG_DEBUG, TAG, "SDP: Connection to SDP established.");

				//	Service record, to be included in the registry of the SDP-Server
				sdp_record_t record;

				//	To create the record, several lists must be put together
				sdp_list_t *languages, *service_class_id, *profile_sequence, *access_protocol_sequence, *root_list, *access_protocol, *protocol_list[3];

				//	The uuid_t data type is used to represent the 128-bit UUID that
				//	is used as un universal unique identifier. SEE THE THESIS, SUBSECTION 2.2.2
				uuid_t root_uuid, hid_uuid, l2cap_uuid, hidp_uuid;

				//	BluetoothProfileDescriptorList. SEE THE THESIS, SUBSECTION 4.2.6
				sdp_profile_desc_t sdp_profile[1];

				//	LanguageBaseAttributeIDList, SEE THE THESIS, SUBSECTION 4.2.4
				sdp_lang_attr_t base_language;

				//	The sdp_data_t structure stores information in a service record
				sdp_data_t *psm, *hid_descriptor_list, *hid_descriptor_formatted_list, *language_base_list, *language_base_formatted_list;

				//	SDP-specific types: 8- and 16- bit unsigned integers and a 8-bit string
				uint8_t data_type_uint8 	= SDP_UINT8;
				uint8_t data_type_uint16 	= SDP_UINT16;
				uint8_t data_type_str8	 	= SDP_TEXT_STR8;


				int length[2];

				//	arrays used to form the sdp specific strcuture of sequence attribites: descriptor and language base
				void *data_types[2] , *descriptor_array[2], *language_base_array[2];

				memset(&record, 0, sizeof(sdp_record_t));

				//	Assigning the Record Handle, SEE THE THESIS, SUBSECTION 4.2.2
				record.handle = handle;

				// Putting together attributes, common to all services.
				// SEE THE THESIS, SECTION 4.2

			    // Setting the Browse Group and making
				// the service record publicly available.
				// SEE THE THESIS, SUBSECTION 4.2.3
			    sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
			    root_list = sdp_list_append(0, &root_uuid);
			    sdp_set_browse_groups( &record, root_list );


				// The LanguageBaseAttributeIDList
			    // SEE THE THESIS, SUBSECTION 4.2.4
				base_language.code_ISO639 = (0x65 << 8) | 0x6e;
				base_language.base_offset = SDP_PRIMARY_LANG_BASE;
				base_language.encoding = 106;

				languages = sdp_list_append(0, &base_language);
				sdp_set_lang_attr(&record, languages);
				sdp_list_free(languages, 0);


				//	The ServiceClassIDList
				//	SEE THE THESIS, SUBSECTION 4.2.1
				sdp_uuid16_create(&hid_uuid, HID_SVCLASS_ID);
				service_class_id = sdp_list_append(0, &hid_uuid);
				sdp_set_service_classes(&record, service_class_id);

				// The BluetoothProfileDescriptorList
				// SEE THE THESIS, SUBSECTION 4.2.6
				sdp_uuid16_create(&sdp_profile[0].uuid, HID_PROFILE_ID);
				sdp_profile[0].version = 0x0100;
				profile_sequence = sdp_list_append(0, sdp_profile);
				sdp_set_profile_descs(&record, profile_sequence);


				// The ProtocolDescriptorList
				// SEE THE THESIS, SUBSECTION 4.2.5

				//	We set information about:

				//	A) Control Channel ->
				//	B) Interruption Channel

				//	We use the protocol_list to bind information
				//	about L2CAP and HID stack level

				//	A) Control Channel (PSM: 0x11)
				// 	1) Set info on L2CAP
				sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
				protocol_list[1] = sdp_list_append(0, &l2cap_uuid);
				psm = sdp_data_alloc(SDP_UINT16, &control_channel_psm);
				protocol_list[1] = sdp_list_append(protocol_list[1], psm);
				access_protocol_sequence = sdp_list_append(0, protocol_list[1]);
				// 	2) Set info on HID
				sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
				protocol_list[2] = sdp_list_append(0, &hidp_uuid);
				access_protocol_sequence = sdp_list_append(access_protocol_sequence, protocol_list[2]);
				// bind to DecriptorList
				access_protocol = sdp_list_append(0, access_protocol_sequence);
				sdp_set_access_protos(&record, access_protocol);

				//	B) Interruption Channel (PSM: 0x13)
				// 	1) Set info on L2CAP
				protocol_list[1] = sdp_list_append(0, &l2cap_uuid);
				psm = sdp_data_alloc(SDP_UINT16, &interruption_channel_psm);
				protocol_list[1] = sdp_list_append(protocol_list[1], psm);
				access_protocol_sequence = sdp_list_append(0, protocol_list[1]);
				// 	2) Set info on HID
				sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
				protocol_list[2] = sdp_list_append(0, &hidp_uuid);
				access_protocol_sequence = sdp_list_append(access_protocol_sequence, protocol_list[2]);

				access_protocol = sdp_list_append(0, access_protocol_sequence);
				sdp_set_add_access_protos(&record, access_protocol);



				//	Setting the information on device, author and service,
				//	throuth the human-readable attributes
				//  SEE THE THESIS, SUBSECTION 4.2.4
				sdp_set_info_attr(&record, SERVICE_NAME, SERVICE_INFO, AUTHOR_INFO);

				// After putting together the attributes, common to all services,
				// we bind the attributes that are specific to the HID service.
				// SEE THE THESIS, SECTION 4.3

				//	Adding all HID attributes (mandatory or optional)
				//	explained in the THESIS (4.3.1 - 4.3.13)

				//  SEE THE THESIS, SUBSECTION 4.3.1
				if(descriptor_is_relative){

					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_DEVICE_RELEASE_NUMBER,
										SDP_UINT16,
										&attr_release_number_mouse_keyboard);

				}else{

					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_DEVICE_RELEASE_NUMBER,
										SDP_UINT16,
										&attr_release_number_pointer_keyboard);

				}



					//	 SEE THE THESIS, SUBSECTION 4.3.2
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_PARSER_VERSION,
										SDP_UINT16,
										&attr_parser_version);

					//  SEE THE THESIS, SUBSECTION 4.3.3
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_DEVICE_SUBCLASS,
										SDP_UINT8,
										&attr_device_subclass);

					//  SEE THE THESIS, SUBSECTION 4.3.4
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_COUNTRY_CODE,
										SDP_UINT8,
										&attr_country_code);

					//  SEE THE THESIS, SUBSECTION 4.3.5
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_VIRTUAL_CABLE,
										SDP_BOOL,
										&attr_virtual_cable);

					//  SEE THE THESIS, SUBSECTION 4.3.6
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_RECONNECT_INITIATE,
										SDP_BOOL,
										&attr_reconnect_initiate);


					//	SEE THE THESIS, SUBSECTION 4.3.13

					//	Adding the HIDDescriptorList attribute is more complex,
					//  thus it is data sequence.
					//
					//	The attribute contains two things:
					// 	A) The descriptor type as unsigned integer (In our case it is a report descriptor)
					//  B) The two descriptors as string sequence (keyboard + mouse or keyboard + pointer)

					data_types[0] = &data_type_uint8;
					data_types[1] = &data_type_str8;

					// We check the descriptor_is_realtive value to
					// find out, if the keyboard + mouse or keyboard + pointer
					// service description is to be added.
					if(descriptor_is_relative){

					descriptor_array[0] = &hid_descriptor_type;
					descriptor_array[1] =(uint8_t *) attr_hid_descriptor_relative;
					length[0] = 0;
					length[1] = sizeof(attr_hid_descriptor_relative);

					}else{

					descriptor_array[0] = &hid_descriptor_type;
					descriptor_array[1] =(uint8_t *) attr_hid_descriptor_absolute;
					length[0] = 0;
					length[1] = sizeof(attr_hid_descriptor_absolute);

					}
					//	We bind the array containing the type and the array containing the values
					//  with the  sdp_seq_alloc_with_length function
					hid_descriptor_list = sdp_seq_alloc_with_length( data_types, descriptor_array, length, 2 );

					//	The newly created array contains all information, so it is used to create
					//  the list from the right SDP-specific type (SDP_SEQ8)
					hid_descriptor_formatted_list = sdp_data_alloc( SDP_SEQ8, hid_descriptor_list );
					//	Finally the list is added as un SDP-attribute
					sdp_attr_add( &record, SDP_ATTR_HID_DESCRIPTOR_LIST, hid_descriptor_formatted_list );
					// Done!

					//	The same is also done with the HIDLANGIDBaseList
					//	SEE THE THESIS, SUBSECTION 4.3.12
					data_types[0] = &data_type_uint16;
					data_types[1] = &data_type_uint16;
					language_base_array[0] = &attr_language_base[0];
					language_base_array[1] = &attr_language_base[1];

					//sizeof(attr_language_base) is devided by two, since values are 16-bit integers (not 8-bit like with the HIDDecriptorList)
					language_base_list = sdp_seq_alloc(data_types, language_base_array, sizeof(attr_language_base) / 2);
					language_base_formatted_list = sdp_data_alloc(SDP_SEQ8, language_base_list);
					sdp_attr_add(&record, SDP_ATTR_HID_LANG_ID_BASE_LIST, language_base_formatted_list);
					// Done!

					//	 SEE THE THESIS, SUBSECTION 4.3.7
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_SDP_DISABLE,
										SDP_BOOL,
										&attr_sdp_disable);

					//	 SEE THE THESIS, SUBSECTION 4.3.8
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_BATTERY_POWER,
										SDP_BOOL,
										&attr_battery_power);

					//	 SEE THE THESIS, SUBSECTION 4.3.9
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_REMOTE_WAKEUP,
										SDP_BOOL,
										&attr_remote_wake);

					//	 SEE THE THESIS, SUBSECTION 4.3.10
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_PROFILE_VERSION,
										SDP_UINT16,
										&attr_profile_version);

//					sdp_attr_add_new(	&record,
//										SDP_ATTR_HID_SUPERVISION_TIMEOUT,
//										SDP_UINT16,
//										&attr_supervision_timeout);

					//	 SEE THE THESIS, SUBSECTION 4.3.6
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_NORMALLY_CONNECTABLE,
										SDP_BOOL,
										&attr_normally_connectable);

					//	 SEE THE THESIS, SUBSECTION 4.3.11
					sdp_attr_add_new(	&record,
										SDP_ATTR_HID_BOOT_DEVICE,
										SDP_BOOL,
										&attr_boot_device);


					//	At last the record is good to go and could be added to the sdp registry!
					if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {

						//	LOGCAT:
						__android_log_print(ANDROID_LOG_DEBUG, TAG, "SDP: Registration of new record failed.");
						return CODE_RECORD_REGISTRATION_FAILED;

					}

					//	LOGCAT:
					__android_log_print(ANDROID_LOG_DEBUG, TAG, "SDP: Registration of new record successful.");

			sdp_close(session);

			return CODE_RECORD_REGISTERED;
	
}