windows_bt_log_impl.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <windows.h>
  4. #include <sys/stat.h>
  5. #include <sys/types.h>
  6. #include "windows_bt_log_impl.h"
  7. #include "base\byteorder.h"
  8. #include "logging\bt_log_impl.h"
  9. #include "logging\bt_log.h"
  10. #define FUNCTION_WINDOWS_LOG_PRINT_IN_WINDOW // becareful, printf need too long time
  11. #define FUNCTION_WINDOWS_LOG_TXT_FILE
  12. #define FUNCTION_WINDOWS_LOG_CFA_FILE
  13. #define LOG_FILE_PATH_MAX_LENGTH (0x400)
  14. /**
  15. * number of seconds from 1 Jan. 1601 00:00 to 1 Jan 1970 00:00 UTC
  16. */
  17. #define EPOCH_DIFF 11644473600LL
  18. #define H4_CMD 0x01
  19. #define H4_ACL 0x02
  20. #define H4_SCO 0x03
  21. #define H4_EVT 0x04
  22. #define H4_ISO 0x05
  23. #define LOG_FILE_PRINT_BUFFER_MAX_LENGTH (0x1000)
  24. static pthread_mutex_t print_lock;
  25. static const char *get_packet_type_str(uint8_t packet_type, uint8_t in)
  26. {
  27. switch (packet_type)
  28. {
  29. case H4_CMD:
  30. return ("CMD => ");
  31. break;
  32. case H4_EVT:
  33. return ("EVT <= ");
  34. break;
  35. case H4_ACL:
  36. if (in)
  37. {
  38. return ("ACL <= ");
  39. }
  40. else
  41. {
  42. return ("ACL => ");
  43. }
  44. break;
  45. case H4_SCO:
  46. if (in)
  47. {
  48. return ("SCO <= ");
  49. }
  50. else
  51. {
  52. return ("SCO => ");
  53. }
  54. break;
  55. case H4_ISO:
  56. if (in)
  57. {
  58. return ("ISO <= ");
  59. }
  60. else
  61. {
  62. return ("ISO => ");
  63. }
  64. break;
  65. default:
  66. return "";
  67. }
  68. }
  69. static void create_file(char *file_name)
  70. {
  71. FILE *file;
  72. file = fopen(file_name, "r");
  73. if (file == NULL)
  74. {
  75. file = fopen(file_name, "w");
  76. }
  77. //关闭文件
  78. fclose(file);
  79. }
  80. static void delete_file(char *file_name)
  81. {
  82. remove(file_name);
  83. }
  84. static void get_log_file_path(char *p_log_path)
  85. {
  86. char exe_path[LOG_FILE_PATH_MAX_LENGTH];
  87. GetModuleFileName(NULL, exe_path, LOG_FILE_PATH_MAX_LENGTH);
  88. *strrchr(exe_path, '\\') = 0;
  89. sprintf(p_log_path, "%s\\log", exe_path);
  90. }
  91. static void get_log_txt_file_name(char *file_path)
  92. {
  93. char log_path[LOG_FILE_PATH_MAX_LENGTH];
  94. // get log path
  95. get_log_file_path(log_path);
  96. sprintf(file_path, "%s\\log.txt", log_path);
  97. }
  98. static void get_log_cfa_file_name(char *file_path)
  99. {
  100. char log_path[LOG_FILE_PATH_MAX_LENGTH];
  101. // get log path
  102. get_log_file_path(log_path);
  103. sprintf(file_path, "%s\\log.cfa", log_path);
  104. }
  105. static void log_printf_dump(uint8_t level, const char *format, va_list argptr)
  106. {
  107. char log_printf_buffer[LOG_FILE_PRINT_BUFFER_MAX_LENGTH];
  108. char msg_str[LOG_FILE_PRINT_BUFFER_MAX_LENGTH];
  109. int len = vsnprintf(msg_str, sizeof(msg_str), format, argptr);
  110. ARG_UNUSED(len);
  111. char timestamp_str[0x100];
  112. SYSTEMTIME timestamp;
  113. GetLocalTime(&timestamp);
  114. snprintf(timestamp_str, sizeof(timestamp_str), "%04u-%02u-%02u %02u:%02u:%02u.%03u",
  115. timestamp.wYear, timestamp.wMonth, timestamp.wDay, timestamp.wHour, timestamp.wMinute,
  116. timestamp.wSecond, timestamp.wMilliseconds);
  117. int total_len = snprintf(log_printf_buffer, sizeof(log_printf_buffer), "[%s] [0x%lx] %s",
  118. timestamp_str, GetCurrentThreadId(), msg_str);
  119. ARG_UNUSED(total_len);
  120. pthread_mutex_lock(&print_lock);
  121. #ifdef FUNCTION_WINDOWS_LOG_TXT_FILE
  122. char log_txt_file_name[LOG_FILE_PATH_MAX_LENGTH];
  123. get_log_txt_file_name(log_txt_file_name);
  124. FILE *file;
  125. file = fopen(log_txt_file_name, "a");
  126. fprintf(file, log_printf_buffer);
  127. fclose(file);
  128. #endif
  129. // printf("total_len: %d\n", total_len);
  130. #ifndef FUNCTION_WINDOWS_LOG_PRINT_IN_WINDOW
  131. if (level <= LOG_IMPL_LEVEL_INF)
  132. #endif
  133. {
  134. // print in window.
  135. printf(log_printf_buffer);
  136. }
  137. pthread_mutex_unlock(&print_lock);
  138. }
  139. void create_btsnoop_header(uint8_t *buffer, uint32_t ts_usec_high, uint32_t ts_usec_low,
  140. uint32_t cumulative_drops, uint8_t packet_type, uint8_t in, uint16_t len)
  141. {
  142. uint32_t packet_flags = 0;
  143. if (in)
  144. {
  145. packet_flags |= 1;
  146. }
  147. switch (packet_type)
  148. {
  149. case H4_CMD:
  150. case H4_EVT:
  151. packet_flags |= 2;
  152. default:
  153. break;
  154. }
  155. sys_put_be32(len, buffer + 0); // Original Length
  156. sys_put_be32(len, buffer + 4); // Included Length
  157. sys_put_be32(packet_flags, buffer + 8); // Packet Flags
  158. sys_put_be32(cumulative_drops, buffer + 12); // Cumulativ Drops
  159. sys_put_be32(ts_usec_high, buffer + 16); // Timestamp Microseconds High
  160. sys_put_be32(ts_usec_low, buffer + 20); // Timestamp Microseconds Low
  161. buffer[24] = packet_type;
  162. }
  163. static void log_packet_dump(uint8_t packet_type, uint8_t in, uint8_t *packet, uint16_t len)
  164. {
  165. char log_printf_buffer[LOG_FILE_PRINT_BUFFER_MAX_LENGTH];
  166. const char *packet_type_str = get_packet_type_str(packet_type, in);
  167. FILE *file;
  168. char msg_str[LOG_FILE_PRINT_BUFFER_MAX_LENGTH];
  169. log_hex_dump(msg_str, sizeof(msg_str), packet, len);
  170. char timestamp_str[0x100];
  171. SYSTEMTIME timestamp;
  172. GetLocalTime(&timestamp);
  173. snprintf(timestamp_str, sizeof(timestamp_str), "%04u-%02u-%02u %02u:%02u:%02u.%3u",
  174. timestamp.wYear, timestamp.wMonth, timestamp.wDay, timestamp.wHour, timestamp.wMinute,
  175. timestamp.wSecond, timestamp.wMilliseconds);
  176. int total_len = snprintf(log_printf_buffer, sizeof(log_printf_buffer), "[%s] [0x%lx] %s %s\n",
  177. timestamp_str, GetCurrentThreadId(), packet_type_str, msg_str);
  178. ARG_UNUSED(total_len);
  179. pthread_mutex_lock(&print_lock);
  180. #ifdef FUNCTION_WINDOWS_LOG_CFA_FILE
  181. uint8_t header_btsnoop[25];
  182. // uint32_t tv_sec = 0;
  183. // uint32_t tv_us = 0;
  184. uint64_t ts_usec;
  185. FILETIME file_time;
  186. ULARGE_INTEGER now_time;
  187. SystemTimeToFileTime(&timestamp, &file_time);
  188. now_time.LowPart = file_time.dwLowDateTime;
  189. now_time.HighPart = file_time.dwHighDateTime;
  190. ts_usec = 0xdcddb30f2f8000LLU + now_time.QuadPart / 10 - EPOCH_DIFF * 1000000LLU;
  191. // append packet type to pcap header
  192. create_btsnoop_header(header_btsnoop, ts_usec >> 32, ts_usec & 0xFFFFFFFF, 0, packet_type, in,
  193. len + 1);
  194. char log_cfa_file_name[LOG_FILE_PATH_MAX_LENGTH];
  195. get_log_cfa_file_name(log_cfa_file_name);
  196. // printf("packet len: %d, packet: %s\n", len, msg_str);
  197. file = fopen(log_cfa_file_name, "ab");
  198. fwrite(header_btsnoop, sizeof(header_btsnoop), 1, file);
  199. fwrite(packet, len, 1, file);
  200. fclose(file);
  201. #endif
  202. #ifdef FUNCTION_WINDOWS_LOG_TXT_FILE
  203. char log_txt_file_name[LOG_FILE_PATH_MAX_LENGTH];
  204. get_log_txt_file_name(log_txt_file_name);
  205. file = fopen(log_txt_file_name, "a");
  206. fprintf(file, log_printf_buffer);
  207. fclose(file);
  208. #endif
  209. // printf("total_len: %d\n", total_len);
  210. #ifdef FUNCTION_WINDOWS_LOG_PRINT_IN_WINDOW
  211. // print in window.
  212. printf(log_printf_buffer);
  213. #endif
  214. pthread_mutex_unlock(&print_lock);
  215. }
  216. static void log_point_dump(uint32_t point)
  217. {
  218. }
  219. static void log_init(void)
  220. {
  221. char log_path[LOG_FILE_PATH_MAX_LENGTH];
  222. // get log path
  223. get_log_file_path(log_path);
  224. mkdir(log_path);
  225. pthread_mutex_init(&print_lock, NULL);
  226. #ifdef FUNCTION_WINDOWS_LOG_TXT_FILE
  227. char log_txt_file_name[LOG_FILE_PATH_MAX_LENGTH];
  228. get_log_txt_file_name(log_txt_file_name);
  229. delete_file(log_txt_file_name);
  230. create_file(log_txt_file_name);
  231. #endif
  232. #ifdef FUNCTION_WINDOWS_LOG_CFA_FILE
  233. char log_cfa_file_name[LOG_FILE_PATH_MAX_LENGTH];
  234. get_log_cfa_file_name(log_cfa_file_name);
  235. delete_file(log_cfa_file_name);
  236. create_file(log_cfa_file_name);
  237. // write BTSnoop file header
  238. const uint8_t file_header[] = {
  239. // Identification Pattern: "btsnoop\0"
  240. 0x62,
  241. 0x74,
  242. 0x73,
  243. 0x6E,
  244. 0x6F,
  245. 0x6F,
  246. 0x70,
  247. 0x00,
  248. // Version: 1
  249. 0x00,
  250. 0x00,
  251. 0x00,
  252. 0x01,
  253. // Datalink Type: 1002 - H4
  254. 0x00,
  255. 0x00,
  256. 0x03,
  257. 0xEA,
  258. };
  259. FILE *file;
  260. file = fopen(log_cfa_file_name, "w");
  261. fwrite(file_header, sizeof(file_header), 1, file);
  262. fclose(file);
  263. // uint8_t packet[] = {0x03, 0x0c, 0x00};
  264. // log_packet_dump(1, 0, packet, sizeof(packet));
  265. // log_packet_dump(1, 0, packet, sizeof(packet));
  266. // log_packet_dump(1, 0, packet, sizeof(packet));
  267. // log_packet_dump(1, 0, packet, sizeof(packet));
  268. // log_packet_dump(1, 0, packet, sizeof(packet));
  269. #endif
  270. }
  271. static const bt_log_impl_t log_impl = {
  272. log_init,
  273. log_packet_dump,
  274. log_printf_dump,
  275. log_point_dump,
  276. };
  277. const bt_log_impl_t *bt_log_impl_local_instance(void)
  278. {
  279. return &log_impl;
  280. }