3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2012-2013 Intel Corporation
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
46 } __attribute__ ((packed));
51 } __attribute__ ((packed));
53 static void print_cmd(uint16_t opcode, const uint8_t *buf, uint8_t plen)
57 printf(" Write_Inquiry_Scan_Type [type=%u]", buf[0]);
60 printf(" Write_Page_Scan_Type [type=%u]", buf[0]);
63 printf(" Write_BD_ADDR [bdaddr=%02x:%02x:%02x:%02x:%02x:%02x]",
64 buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]);
67 printf(" Write_Local_Supported_Features");
68 printf(" [features=%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x]",
69 buf[0], buf[1], buf[2], buf[3],
70 buf[4], buf[5], buf[6], buf[7]);
73 printf(" Super_Peek_Poke [type=%u]", buf[0]);
76 printf(" FM_RDS_Command [register=0x%02x,mode=%u]",
80 printf(" Update_UART_Baud_Rate");
83 printf(" Write_SCO_PCM_Int_Param");
86 printf(" Write_PCM_Data_Format_Param");
89 printf(" Write_SCO_Time_Slot [slot=%u]", buf[0]);
92 printf(" Write_Collaboration_Mode");
95 printf(" Write_RAM [address=0x%08x]",
96 buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24);
99 printf(" Launch_RAM [address=0x%08x]",
100 buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24);
103 printf(" Write_PCM_Pins");
108 static void analyze_memory(const uint8_t *buf, size_t len)
110 const uint8_t *ptr = buf;
111 const struct neg_cmd *neg;
112 const struct alive_pkt *alive;
113 uint16_t pkt_len, opcode;
114 uint8_t pkt_type, plen;
116 while (ptr < buf + len) {
117 pkt_len = ptr[0] | ptr[1] << 8;
120 printf("len=%-3u type=%u,", pkt_len, pkt_type);
124 opcode = ptr[3] | ptr[4] << 8;
126 printf("%-5s opcode=0x%04x plen=%-3u", "cmd",
128 print_cmd(opcode, ptr + 6, plen);
132 printf("%-5s plen=%-2u", "neg", plen);
133 neg = (void *) (ptr + 4);
134 printf(" [ack=%u baud=%u proto=0x%02x sys_clk=%u]",
135 neg->ack, neg->baud, neg->proto, neg->sys_clk);
139 printf("%-5s plen=%-2u", "alive", plen);
140 alive = (void *) (ptr + 4);
141 printf(" [mid=0x%02x]", alive->mid);
144 opcode = ptr[3] | ptr[4] << 8;
146 printf("%-5s opcode=0x%04x plen=%-3u", "radio",
148 print_cmd(opcode, ptr + 6, plen);
161 static void analyze_file(const char *pathname)
167 printf("Analyzing %s\n", pathname);
169 fd = open(pathname, O_RDONLY | O_CLOEXEC);
171 perror("Failed to open file");
175 if (fstat(fd, &st) < 0) {
176 fprintf(stderr, "Failed get file size\n");
181 if (st.st_size == 0) {
182 fprintf(stderr, "Empty file\n");
187 map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
188 if (!map || map == MAP_FAILED) {
189 fprintf(stderr, "Failed to map file\n");
194 analyze_memory(map, st.st_size);
196 munmap(map, st.st_size);
200 static void usage(void)
202 printf("Nokia Bluetooth firmware analyzer\n"
204 printf("\tnokfw [options] <file>\n");
206 "\t-h, --help Show help options\n");
209 static const struct option main_options[] = {
210 { "version", no_argument, NULL, 'v' },
211 { "help", no_argument, NULL, 'h' },
215 int main(int argc, char *argv[])
222 opt = getopt_long(argc, argv, "vh", main_options, NULL);
228 printf("%s\n", VERSION);
238 if (argc - optind < 1) {
239 fprintf(stderr, "No input firmware files provided\n");
243 for (i = optind; i < argc; i++)
244 analyze_file(argv[i]);