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)
Ответ на: комментарий от irton

сделай объявление поля структуры по образу https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/src/hcid.h#n39

char *defaultpin;

char - один символ. char* - это указатель на то место в памяти, где начинается последовательность символов (строка). хотя кому я все это объясняю.

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

Ну тут трюк в том, что...

по своей сути GLib для С является аналогом STL для С++. Не совсем, плюс-минус так, но всё же. Никто же там код особо не лопатит на предмет того, как там в каком случае память резервируется-освобождается? Здесь так же. Память выделили-память освободили. И то, если надо, т.к. в случае, если программа запросила память и просто отработала, без циклов, то можно даже g_free не дёргать. Система по завершении работы сама все ресурсы зачистит.

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

спокойно, я теоретически накачан, на ассемблере немного писал лабораторные себе и товарищам, лет 15 назад.

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

сделай как здесь

str = g_key_file_get_string(config, "General", "Name", &err);
	if (err) {
		DBG("%s", err->message);
		g_clear_error(&err);
	} else {
		DBG("name=%s", str);
		g_free(main_opts.name);
		main_opts.name = str;
	}

не освобождают, потому что значение указателя переприсваивается полю структуры, которое используется в дальнейшем, иначе нет смысла его (поле) вопще вводить в расмотрение.

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

Чуть выше ответил почему.

Если память не выделяется-не освобождается в цикле, а программа просто запросила память и отработала до конца, то можно и не чистить. Система по завершении программы сама зачистит ресурсы за ней. И память в первую очередь.

Вот поэтому и не чистят.

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

Красота, спасибо вам. conalex, Moisha_Liberman, Toxo1

Изначальная ошибка патча была в том что использовал val вместо str и задал char defaultpin; вместо char *defaultpin;

Преобразование типа в memcpy сейчас не требуется.

Насчет g_free(str) давайте определимся, чтобы более законченное решение стало. пока писал уже ответили :)

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

Дык. Незачто.

Решение для проверки я же выше кидал: Прошу помощи по типу данных в С (комментарий)

=) С указаниями типов. По месту подтесать и надо было.

Насчет g_free(str) давайте определимся, чтобы более законченное решение стало.

В смысле? Если надо, так освобождайте, если ненадо, так и забить можно. Зависит от логики приблуды. Но красивее и более методически правильно освобождать.

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

Вообще, от себя могу совет дать.

Чтобы не было болезни грязных рук, рекомендую поставить splint. Это secure programming lint, через syntastic у меня он к vim'у привязан.

Как только я открываю файл на редактирование или пытаюсь его записать, он мне автоматом ищет мои ошибки и косяки. Нагадить в коде становится очень сложно. Ну только если забивать на предупреждения целенаправленно.

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

Удачи в любом случае.

Но насчёт splint я Вам настоятельно рекомендую им поинтересоваться. Это работает без компиляции, ещё на этапе редактирования исходника. Реже будете от компилятора по соплями получать, да и приставка secure programming там в названии абсолютно не зря болтается. В сишечке ещё и по безопасности можно отловить. На что, кстати, Toxo1 абсолютно верно и намекал.

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

задал char defaultpin; вместо char *defaultpin;

Я тебе сразу это написал в третьем сообщении темы. Непонятно что вы тут делали все 50 постов.

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

ну у вас то было const char* defaultpin;

а у меня char *defaultpin;

фиг его знает как эта звездочка должна стоять, а 50 постов мы еще val на str еще меняли.

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