LINUX.ORG.RU

Прошу помощи по типу данных в С

 , ,


0

1

Написал патч для bluez. Используя встроенный плагин autopair при условии что используется capability=noinputnooutput пин-код для паринга устройств берем из файла main.conf

При компиляции получаю предупреждение:

plugins/autopair.c:158:18: предупреждение: при передаче аргумента 2 «memcpy» целое преобразуется в указатель без приведения типа [-Wint-conversion]
   memcpy(pinbuf, main_opts.defaultpin, 4);
                  ^~~~~~~~~
замечание: ожидался тип «const void * restrict», но аргумент имеет тип «gchar {aka char}»
 extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
              ^~~~~~

Собственно вопрос: какой тип правильнее будет выставить для значения в main.conf типа DefaultPin = 5421 я так понимаю что char тип не очень подходит?

# cat ./bluez.patch 
--- ./main.c_old	2018-06-01 16:37:36.000000000 +0800
+++ ./src/main.c	2018-11-28 13:56:32.489196607 +0800
@@ -90,6 +90,7 @@
 	"MultiProfile",
 	"FastConnectable",
 	"Privacy",
+	"DefaultPin",
 	NULL
 };
 
@@ -317,6 +318,16 @@
 		g_free(str);
 	}
 
+	val = g_key_file_get_string(config, "General",
+						"DefaultPin", &err);
+	if (err) {
+		DBG("%s", err->message);
+		g_clear_error(&err);
+	} else {
+		DBG("defaultpin=%d", val);
+		main_opts.defaultpin = val;
+	}
+
 	str = g_key_file_get_string(config, "General", "Name", &err);
 	if (err) {
 		DBG("%s", err->message);
@@ -434,6 +445,7 @@
 	main_opts.reverse_sdp = TRUE;
 	main_opts.name_resolv = TRUE;
 	main_opts.debug_keys = FALSE;
+	main_opts.defaultpin = 0000;
 
 	if (sscanf(VERSION, "%hhu.%hhu", &major, &minor) != 2)
 		return;
--- ./hcid.h_old	2018-06-01 16:37:36.000000000 +0800
+++ ./src/hcid.h	2018-11-28 13:54:29.753199017 +0800
@@ -41,6 +41,7 @@
 	uint32_t	pairto;
 	uint32_t	discovto;
 	uint8_t		privacy;
+	char		defaultpin;
 
 	gboolean	reverse_sdp;
 	gboolean	name_resolv;
--- ./autopair.c_old	2018-11-30 14:32:55.000000000 +0800
+++ ./plugins/autopair.c	2018-12-05 10:10:59.000000000 +0800
@@ -35,12 +35,14 @@
 
 #include "src/plugin.h"
 #include "src/adapter.h"
 #include "src/device.h"
 #include "src/log.h"
 #include "src/storage.h"
+#include "src/agent.h"
 
 /*
  * Plugin to handle automatic pairing of devices with reduced user
@@ -62,6 +64,8 @@
 	char pinstr[7];
 	char name[25];
 	uint32_t class;
+	uint8_t io_cap;
+	struct agent *agent;
 
 	ba2str(device_get_address(device), addr);
 
@@ -143,7 +147,18 @@
 		}
 		break;
 	}
-
+	/*check capability=NOINPUTNOOUTPUT and use DefaultPin=0000 or from main.conf if available*/
+	if (agent)
+	    io_cap = agent_get_io_capability(agent);
+	
+	if (io_cap == 0x03) {
+	    DBG("capability set to NOINPUTNOOUTPUT use defaultpin");
+		if (attempt > 1)
+			return 0;
+		memcpy(pinbuf, main_opts.defaultpin, 4);
+		return 4;
+	}
+	
 	return 0;
 }
★★★★★

Последнее исправление: irton (всего исправлений: 2)
Ответ на: комментарий от anonymous2

Если честно я вобще этот язык не знаю, но патч мне нужен, а разрабы не торопятся реализовать, они mesh пилят.

по сути мой патч сделан на основе подобного же кода в самом bluez. В ./src/hcid.h задается тип для получаемого значения, я подозреваю что char это не подходящий тип.

в /plugins/autopair.c я значение из main_opts.defaultpin передаю для паринга устройств, предварительно проверив что capability в нужном значении.

Вроде как все логично, для передачи фиксированного значения пинкода, они используют

memcpy(pinbuf, "0000", 4);

irton ★★★★★
() автор топика
Ответ на: комментарий от irton

По патчу у тебя литерал 0000 (int? short?) присваивается к char defaultpin получается?

Может ты хотел сделать

+	main_opts.defaultpin = "0000";
+	const char*		defaultpin;

?

EXL ★★★★★
()
Ответ на: комментарий от EXL

По патчу у тебя литерал 0000 (int? short?) присваивается к char defaultpin получается?

да. но я незнаю какой тип сделать. Если допустим int будет, то 0000 не запишутся ли как просто 0 ? тут же надо чтобы и 0001 и 0010 тоже были допустимыми значениями и первые нули не отбрасывались.

Задача брать значение из конфига main.conf и присваивать его main_opts.defaultpin потом это значение использовать при автопаринге.

irton ★★★★★
() автор топика
Ответ на: комментарий от EXL

main_opts.defaultpin = «0000»;

Я так понял, это я задаю значение, если в main.conf конфиге DefaultPin вобще не задан.

irton ★★★★★
() автор топика
Ответ на: комментарий от EXL

По патчу не видно, но main_opts это массив, в который складываются значения полученные из main.conf, потом они используются в разных частях кода.

irton ★★★★★
() автор топика
Ответ на: комментарий от irton

Я так понял, это я задаю значение, если в main.conf конфиге DefaultPin вобще не задан.

Просто вот эта вот конструкция memcpy(pinbuf, main_opts.defaultpin, 4); копирует в pinbuf четыре байта начиная с адреса 0x0000, если defaultpin у тебя 0000.

Мне не видно всю картину и с bluez я не знаком. Но по идее этот DefaultPin должен храниться как массив char[4], то бишь строкой. Тогда эта проблема вообще исчезает:

тут же надо чтобы и 0001 и 0010 тоже были допустимыми значениями и первые нули не отбрасывались.

И да, с этими 0-ями в литералах осторожнее. Так как 0100 это будет восьмеричное число, а не десятериное.

ИМХО тебе нужно подробнее рассказать об этой фиче кому-нибудь заинтересованному в bluez, чтобы он помог тебе с написанием патча и не троллил тебя на незнание C, а реально давал советы. Надеюсь, на этом форуме найдётся такой человек.

Просто так ты можешь кучу выстрелов в ноги и уязвимостей наделать, потому что за C первый раз взялся. Например, пропустить проверку на размер этого DefaultPin в конфиге и тогда в конфиг можно будет записать какой-нибудь треш, сорвать стек и выполнить код из вне.

EXL ★★★★★
()
Ответ на: комментарий от irton

Совсем не знаю что такое bluez и что такое пин.

Но из голого Си - у вас тут

val = g_key_file_get_string
и потом
main_opts.defaultpin = val
. Если посмотреть в определение функции g_key_file_get_string, то оно возвращает gchar*, которое объявлено как char*.
Но даже если вы объявите свой defaultpin как gchar* (что формально будет правильно с точки зрения типов) - это будет наверняка неправильно с точки зрения логики. Надо смотреть внутрь реализации g_key_file_get_string чтобы точно знать указатель на что именно оно возвращает (не общий ли там буфер библиотеки, в частности), или, если лень разбираться - сразу делать memcpy из возвращаемого буфера в свое собственное место для него в defaultpin (который должен быть char[4], если я правильно понимаю что пин это нечто из 4х символов).

Ну и по этому поводу очень хочется ввернуть что-нибудь едкое для ненавистников венгерской нотации. Была бы тут венгерка - не было бы этого вопроса. Мне так кажется.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

g_key_file_get_string еще вижу в коде бывает g_key_file_get_integer, g_key_file_get_boolean

g_key_file_get_boolean мне точно не подходит.

Здесь ввернуть едкое можно что угодно, я не оценю.

irton ★★★★★
() автор топика
Последнее исправление: irton (всего исправлений: 1)
Ответ на: комментарий от irton

Да.

Я так понял, это я задаю значение, если в main.conf конфиге DefaultPin вобще не задан.

Это дефолтное значение которое захардкодили на случай, если в конфиге этот параметр не определён.

Moisha_Liberman ★★
()
Ответ на: Да. от Moisha_Liberman

это не они захардкодили, это я :) я же должен понимать хотя бы в теории чего я пишу.

кавычки конечно обычные, это без проблем

irton ★★★★★
() автор топика
Ответ на: Ну да. Понял. от Moisha_Liberman

я не до конца предупреждения в заглавном сообщении темы написал, исправил. про замечание: ожидался тип «const void * restrict» у меня не было написано.

irton ★★★★★
() автор топика
Ответ на: комментарий от irton

Это следует из сигнатуры ф-ии.

Тут и так ясно. Второй аргумент. Откуда читаем. Это хрестоматийно. =)

void* memcpy(void* dest, const void* src, size_t count);

Moisha_Liberman ★★
()
Ответ на: Это следует из сигнатуры ф-ии. от Moisha_Liberman

size_t count

я так понимаю это защитит меня если будет пинкод больше 4 знаков, но не защитит если пинкод будет с буквами. Ничего, пример и описание в main.conf добавить можно.

irton ★★★★★
() автор топика
Ответ на: комментарий от irton

Нет.

Не защитит. Это просто размер (длина пинкода в символах).

Защита здесь сразу и встроенная. Ф-я, применяемая для чтения значения из конфига по умолчанию возвращает не число, а строку символов. Т.е., нуль будет не нуль как число, а символ нуля (как просто цифровой символ).

Moisha_Liberman ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.