1/* 2 * This is a reverse-engineered driver for mobile WiMAX (802.16e) devices 3 * based on GCT Semiconductor GDM7213 & GDM7205 chip. 4 * Copyright (�) 2010 Yaroslav Levandovsky <leyarx@gmail.com> 5 * 6 * Based on madWiMAX driver writed by Alexander Gordeev 7 * Copyright (C) 2008-2009 Alexander Gordeev <lasaine@lvk.cs.msu.su> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24#include <errno.h> 25#include <fcntl.h> 26#include <getopt.h> 27#include <poll.h> 28#include <signal.h> 29#include <string.h> 30#include <stdio.h> 31#include <stdint.h> //typedef 32#include <stdlib.h> 33#include <unistd.h> 34#include <sys/stat.h> // for mkdir 35#include <sys/time.h> 36#include <sys/wait.h> 37 38#include <libusb/libusb.h> 39 40#include "logging.h" 41#include "protocol.h" 42#include "wimax.h" 43#include "tap_dev.h" 44 45#include "eap_auth.h" 46 47#ifdef WITH_DBUS 48 #include <dbus/dbus.h> 49#endif /* WITH_DBUS */ 50 51#include <openssl/sha.h> 52#include <openssl/aes.h> 53#include "zlib.h" 54/* variables for the command-line parameters */ 55 56static int daemonize = 0; 57 58struct timeval start_sec, curr_sec; // get link status every second 59 60#define QUOTE(name) #name 61#define STR(macro) QUOTE(macro) 62 63#define CONF_DIR STR(CONFDIR) 64 65static char *event_script = CONF_DIR"/event.sh"; 66static char *conf_file = ""; 67static FILE *logfile = NULL; 68static FILE *xml_file = NULL; 69char *pid_file = NULL; 70 71#define MATCH_BY_LIST 0 72#define MATCH_BY_VID_PID 1 73#define MATCH_BY_BUS_DEV 2 74 75//static int match_method = MATCH_BY_LIST; 76 77/* for matching by list... 78typedef struct usb_device_id_t { 79 unsigned short vendorID; 80 unsigned short productID; 81 unsigned short targetVID; 82 unsigned short targetPID; 83} usb_device_id_t; */ 84 85/* list of all known devices 86static usb_device_id_t wimax_dev_ids[] = { 87 { 0x04e8, 0x6761 }, 88 { 0x04e9, 0x6761 }, 89 { 0x04e8, 0x6731 }, 90 { 0x04e8, 0x6780 }, 91};*/ 92 93/* for other methods of matching... 94static union { 95 struct { 96 unsigned short vid; 97 unsigned short pid; 98 }; 99 struct { 100 unsigned int bus; 101 unsigned int dev; 102 }; 103} match_params;*/ 104 105/* USB-related parameters */ 106 107#define IF_DVD 0 108 109#define EP_IN (130 | LIBUSB_ENDPOINT_IN) 110#define EP_OUT (1 | LIBUSB_ENDPOINT_OUT) 111 112#define MAX_PACKET_LEN 0x4000 113 114/* information collector */ 115static struct wimax_dev_status wd_status; 116 117enum wimax_state { 118 WS_DEV_NOT_FOUND = 1, // - Device not found 119 WS_DEV_FOUND, // - Device found 120 WS_ERR_INIT_DRIVER, // - Error init driver 121 WS_RECEIVE_IP, // - Receive ip-address (event script) 122 WS_SCAN, // - Search network 123 WS_NET_NOT_FOUND, // - Network not found 124 WS_NET_FOUND, // - Network found 125 WS_CON_ERR, // - Connection error 126 WS_START_AUTH, // - Start Authentication 127 WS_AUTH_FAILED, // - Authentication Failed 128 WS_DL_XML_START, // - Download XML image started 129 WS_DL_XML_END, // - Download XML image succeed 130}; 131 132static 133const struct { 134 int value; 135 const char *name; 136} wimax_state_names_vals[] = { 137 { WS_DEV_NOT_FOUND, "Device not found" }, 138 { WS_DEV_FOUND, "Device found" }, 139 { WS_ERR_INIT_DRIVER, "Error init driver" }, 140 { WS_RECEIVE_IP, "Receive ip-address (event script)" }, 141 { WS_SCAN, "Search network" }, 142 { WS_NET_NOT_FOUND, "No Signal" }, 143 { WS_NET_FOUND, "Network found" }, 144 { WS_CON_ERR, "Connection error" }, 145 { WS_START_AUTH, "Start Authentication" }, 146 { WS_AUTH_FAILED, "Authentication Failed" }, 147 { WS_DL_XML_START, "Download XML image started" }, 148 { WS_DL_XML_END, "Download XML image succeed" }, 149 { 0, NULL } 150}; 151 152const char * wimax_state_to_name(enum wimax_state state) 153{ 154 size_t itr, max; 155 156 for(max = 0;;max++) 157 if (wimax_state_names_vals[max].name == NULL) 158 break; 159 160 for (itr = 0; itr < max; itr++) 161 if (wimax_state_names_vals[itr].value == state) 162 return wimax_state_names_vals[itr].name; 163 return NULL; 164} 165 166//char *wimax_states[] = {"INIT", "SYNC", "NEGO", "NORMAL", "SLEEP", "IDLE", "HHO", "FBSS", "RESET", "RESERVED", "UNDEFINED", "BE", "NRTPS", "RTPS", "ERTPS", "UGS", "INITIAL_RNG", "BASIC", "PRIMARY", "SECONDARY", "MULTICAST", "NORMAL_MULTICAST", "SLEEP_MULTICAST", "IDLE_MULTICAST", "FRAG_BROADCAST", "BROADCAST", "MANAGEMENT", "TRANSPORT"}; 167 168/* libusb stuff */ 169static struct libusb_context *ctx = NULL; 170static struct libusb_device_handle *devh = NULL; 171static struct libusb_transfer *req_transfer = NULL; 172static int kernel_driver_active = 0; 173 174static unsigned char read_buffer[MAX_PACKET_LEN]; 175 176static int tap_fd = -1; 177static char tap_dev[20] = "wimax%d"; 178static int tap_if_up = 0; 179 180static nfds_t nfds; 181static struct pollfd* fds = NULL; 182 183static int device_disconnected = 0; 184 185static void exit_release_resources(int code); 186static void dbus_conn_info_send(enum wimax_state); // int signal_code 187static void dbus_sig_info_send(void); 188static void dbus_dev_info_send(void); 189static void dbus_bsid_info_send(void); 190static void dbus_percent_info_send(short, short); 191 192#define CHECK_NEGATIVE(x) {if((r = (x)) < 0) return r;} 193#define CHECK_DISCONNECTED(x) {if((r = (x)) == LIBUSB_ERROR_NO_DEVICE) exit_release_resources(0);} 194 195int dbus_use = 0; 196 197#ifdef WITH_DBUS 198DBusConnection *dbus_connection; 199DBusError dbus_error; 200#endif /* WITH_DBUS */ 201 202//DBusGConnection *dbus_connection; 203//GError *dbus_error; 204//DBusGProxy *dbus_proxy; 205/* 206static struct libusb_device_handle* find_wimax_device(void) 207{ 208 struct libusb_device **devs; 209 struct libusb_device *found = NULL; 210 struct libusb_device *dev; 211 struct libusb_device_handle *handle = NULL; 212 int i = 0; 213 int r; 214 215 if (libusb_get_device_list(ctx, &devs) < 0) 216 return NULL; 217 218 while (!found && (dev = devs[i++]) != NULL) { 219 struct libusb_device_descriptor desc; 220 unsigned int j = 0; 221 unsigned short dev_vid, dev_pid; 222 223 r = libusb_get_device_descriptor(dev, &desc); 224 if (r < 0) { 225 continue; 226 } 227 dev_vid = libusb_le16_to_cpu(desc.idVendor); 228 dev_pid = libusb_le16_to_cpu(desc.idProduct); 229 wmlog_msg(1, "Bus %03d Device %03d: ID %04x:%04x", libusb_get_bus_number(dev), libusb_get_device_address(dev), dev_vid, dev_pid); 230 switch (match_method) { 231 case MATCH_BY_LIST: { 232 for (j = 0; j < sizeof(wimax_dev_ids) / sizeof(usb_device_id_t); j++) { 233 if (dev_vid == wimax_dev_ids[j].vendorID && dev_pid == wimax_dev_ids[j].productID) { 234 found = dev; 235 break; 236 } 237 } 238 break; 239 } 240 case MATCH_BY_VID_PID: { 241 if (dev_vid == match_params.vid && dev_pid == match_params.pid) { 242 found = dev; 243 } 244 break; 245 } 246 case MATCH_BY_BUS_DEV: { 247 if (libusb_get_bus_number(dev) == match_params.bus && libusb_get_device_address(dev) == match_params.dev) { 248 found = dev; 249 } 250 break; 251 } 252 } 253 } 254 255 if (found) { 256 r = libusb_open(found, &handle); 257 if (r < 0) 258 handle = NULL; 259 } 260 261 libusb_free_device_list(devs, 1); 262 return handle; 263} 264*/ 265static int switch_wimax_device(void) 266{ 267 struct libusb_device_handle *handle = NULL; 268 int r; 269 handle = libusb_open_device_with_vid_pid(ctx, 0x1076, 0x7f40); 270 if (handle != NULL ){ 271 int disk_if = 0; 272 273 if (libusb_kernel_driver_active(handle, disk_if) == 1) 274 { 275 r = libusb_detach_kernel_driver(handle, disk_if); 276 if (r < 0){ 277 wmlog_msg(1, "Kernel driver detaching (error %d)", r); 278 } else { 279 wmlog_msg(1, "Kernel driver deteched!"); 280 } 281 } else if (libusb_kernel_driver_active(handle, 1) == 1) 282 { 283 r = libusb_detach_kernel_driver(handle, 1); 284 disk_if = 1; 285 if (r < 0){ 286 wmlog_msg(1, "Kernel driver detaching (error %d)", r); 287 } else { 288 wmlog_msg(1, "Kernel driver deteched!"); 289 } 290 } 291 292 r = libusb_claim_interface(handle, disk_if); 293 if (r < 0) { 294 disk_if = 1; 295 r = libusb_claim_interface(handle, disk_if); 296 } 297 if (r < 0) { 298 wmlog_msg(1, "Claim Interface problems (error %d)", r); 299 } 300 else 301 { 302 wmlog_msg(1, "Innterface claimed"); 303 r = libusb_control_transfer(handle, 0xa1, 0xa0, 0, disk_if, read_buffer, 1, 1000); 304 wmlog_msg(1, "Sending Control message (result %d - %s)", r, r ? "bad" : "ok"); 305 libusb_release_interface(handle, disk_if); 306 libusb_close(handle); 307 } 308 return 1; 309 } 310 return 0; 311} 312 313// ***Edited by fanboy*** 314static struct libusb_device_handle* find_wimax_device(void) 315{ 316 struct libusb_device_handle *handle = NULL; 317 318 //Switch modem the same as in usb_modeswitch 319 handle = libusb_open_device_with_vid_pid(ctx, 0x1076, 0x7f00); 320 if (handle == NULL){ 321 if (switch_wimax_device()){ 322 323 int retry = 0; 324 do 325 { 326 sleep(1); // Wait while device switching 327 handle = libusb_open_device_with_vid_pid(ctx, 0x1076, 0x7f00); 328 } 329 while (retry++ < 5 && !handle); 330 331 if (handle) wmlog_msg(2, "Device switched after %d retries.", retry); 332 else wmlog_msg(1, "Device not switched after %d retries.", retry); 333 } 334 } 335 return handle; 336} 337 338static void get_wimax_device(void) 339{ 340 int r; 341 342 devh = find_wimax_device(); 343 if (devh == NULL) { 344 if (dbus_use) dbus_conn_info_send(WS_DEV_NOT_FOUND); 345 wmlog_msg(0, "Could not find/open device"); 346 exit_release_resources(1); 347 } 348 if (dbus_use) dbus_conn_info_send(WS_DEV_FOUND); 349 wmlog_msg(0, "Device found"); 350 if (libusb_kernel_driver_active(devh, IF_DVD) == 1) { 351 kernel_driver_active = 1; 352 r = libusb_detach_kernel_driver(devh, IF_DVD); 353 if (r < 0) { 354 wmlog_msg(0, "kernel driver detach error %d", r); 355 } else { 356 wmlog_msg(0, "detached modem kernel driver"); 357 } 358 } 359 360 r = libusb_claim_interface(devh, 0); 361 if (r < 0) { 362 if (dbus_use) dbus_conn_info_send(WS_DEV_NOT_FOUND); 363 wmlog_msg(0, "Claim usb interface error %d", r); 364 exit_release_resources(1); 365 } 366 wmlog_msg(0, "Claimed interface"); 367} 368 369static int set_data(unsigned char* data, int size) 370{ 371 int r; 372 int transferred; 373 374 wmlog_dumphexasc(3, data, size, "Bulk write:"); 375 376 r = libusb_bulk_transfer(devh, EP_OUT, data, size, &transferred, 0); 377 if (r < 0) { 378 wmlog_msg(1, "bulk write error %d", r); 379 if (r == LIBUSB_ERROR_NO_DEVICE) { 380 if (dbus_use) dbus_conn_info_send(WS_DEV_NOT_FOUND); 381 exit_release_resources(0); 382 } 383 return r; 384 } 385 if (transferred < size) { 386 wmlog_msg(1, "short write (%d)", r); 387 return -1; 388 } 389 return r; 390} 391 392void eap_server_rx(unsigned char *data, int data_len) // Sent data from peer to server 393{ 394 unsigned char req_data[MAX_PACKET_LEN]; 395 int len; 396 397 len = fill_eap_server_rx_req(req_data, data, data_len); 398 set_data(req_data, len); 399} 400 401void eap_key(unsigned char *data, int data_len) 402{ 403 unsigned char req_data[MAX_PACKET_LEN]; 404 int len; 405 406 len = fill_eap_key_req(req_data, data, data_len); 407 set_data(req_data, len); 408} 409 410static void cb_req(struct libusb_transfer *transfer) 411{ 412 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { 413 wmlog_msg(1, "async bulk read error %d", transfer->status); 414 if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) { 415 device_disconnected = 1; 416 return; 417 } 418 } else { 419 wmlog_dumphexasc(3, transfer->buffer, transfer->actual_length, "Async read:"); 420 process_response(&wd_status, transfer->buffer, transfer->actual_length); 421 } 422 if (libusb_submit_transfer(req_transfer) < 0) { 423 wmlog_msg(1, "async read transfer sumbit failed"); 424 } 425} 426 427/* get link_status *//* 428int get_link_status() 429{ 430 return wd_status.link_status; 431}*/ 432 433/* set close-on-exec flag on the file descriptor */ 434int set_coe(int fd) 435{ 436 int flags; 437 438 flags = fcntl(fd, F_GETFD); 439 if (flags == -1) 440 { 441 wmlog_msg(1, "failed to set close-on-exec flag on fd %d", fd); 442 return -1; 443 } 444 flags |= FD_CLOEXEC; 445 if (fcntl(fd, F_SETFD, flags) == -1) 446 { 447 wmlog_msg(1, "failed to set close-on-exec flag on fd %d", fd); 448 return -1; 449 } 450 451 return 0; 452} 453 454/* run specified script */ 455static int raise_event(char *event) 456{ 457 int pid = fork(); 458 459 if(pid < 0) { /* error */ 460 return -1; 461 } else if (pid > 0) { /* parent */ 462 return pid; 463 } else { /* child */ 464 char *args[] = {event_script, event, tap_dev, NULL}; 465 char *env[1] = {NULL}; 466 /* run the program */ 467 execve(args[0], args, env); 468 exit(1); 469 } 470} 471 472/* brings interface up and runs a user-supplied script */ 473static int if_create() 474{ 475 tap_fd = tap_open(tap_dev); 476 if (tap_fd < 0) { 477 wmlog_msg(0, "failed to allocate tap interface"); 478 wmlog_msg(0, 479 "You should have TUN/TAP driver compiled in the kernel or as a kernel module.\n" 480 "If 'modprobe tun' doesn't help then recompile your kernel."); 481 exit_release_resources(1); 482 } 483 tap_set_hwaddr(tap_fd, tap_dev, wd_status.mac); 484 tap_set_mtu(tap_fd, tap_dev, 1386); 485 set_coe(tap_fd); 486 wmlog_msg(0, "Allocated tap interface: %s", tap_dev); 487 wmlog_msg(2, "Starting if-create script..."); 488 raise_event("if-create"); 489 return 0; 490} 491 492/* brings interface up and runs a user-supplied script */ 493static int if_up() 494{ 495 tap_bring_up(tap_fd, tap_dev); 496 wmlog_msg(2, "Starting if-up script..."); 497 raise_event("if-up"); 498 tap_if_up = 1; 499 if (dbus_use) { 500 dbus_conn_info_send(WS_RECEIVE_IP); 501 dbus_bsid_info_send(); 502 } 503 return 0; 504} 505 506/* brings interface down and runs a user-supplied script */ 507static int if_down() 508{ 509 if (!tap_if_up) return 0; 510 tap_if_up = 0; 511 wmlog_msg(2, "Starting if-down script..."); 512 raise_event("if-down"); 513 tap_bring_down(tap_fd, tap_dev); 514 return 0; 515} 516 517/* brings interface down and runs a user-supplied script */ 518static int if_release() 519{ 520 wmlog_msg(2, "Starting if-release script..."); 521 raise_event("if-release"); 522 tap_close(tap_fd, tap_dev); 523 return 0; 524} 525 526/* set link_status *//* 527void set_link_status(int link_status) 528{ 529 wd_status.info_updated |= WDS_LINK_STATUS; 530 531 if (wd_status.link_status == link_status) return; 532 533 if (wd_status.link_status < 2 && link_status == 2) { 534 if_up(); 535 } 536 if (wd_status.link_status == 2 && link_status < 2) { 537 if_down(); 538 } 539 if (link_status == 1) { 540 first_nego_flag = 1; 541 } 542 543 wd_status.link_status = link_status; 544}*/ 545 546/* get state *//* 547int get_state() 548{ 549 return wd_status.state; 550}*/ 551 552/* set state *//* 553void set_state(int state) 554{ 555 wd_status.state = state; 556 wd_status.info_updated |= WDS_STATE; 557 if (state >= 1 && state <= 3 && wd_status.link_status != (state - 1)) { 558 set_link_status(state - 1); 559 } 560}*/ 561 562static int alloc_transfers(void) 563{ 564 req_transfer = libusb_alloc_transfer(0); 565 if (!req_transfer) 566 return -ENOMEM; 567 568 libusb_fill_bulk_transfer(req_transfer, devh, EP_IN, read_buffer, 569 sizeof(read_buffer), cb_req, NULL, 0); 570 571 return 0; 572} 573 574int write_netif(const void *buf, int count) 575{ 576 return tap_write(tap_fd, buf, count); 577} 578 579static int read_tap() 580{ 581 unsigned char buf[MAX_PACKET_LEN]; 582 int hlen = get_header_len(); 583 int r; 584 int len; 585 586 r = tap_read(tap_fd, buf + hlen, MAX_PACKET_LEN - hlen); 587 588 if (r < 0) 589 { 590 wmlog_msg(1, "Error while reading from TAP interface"); 591 return r; 592 } 593 594 if (r == 0) 595 { 596 return 0; 597 } 598 599 len = fill_data_packet_header(buf, r); 600 wmlog_dumphexasc(4, buf, len, "Outgoing packet:"); 601 r = set_data(buf, len); 602 603 return r; 604} 605 606static int process_events_once(int timeout) 607{ 608 struct timeval tv = {0, 0}; 609 int r; 610 int libusb_delay; 611 int delay; 612 unsigned int i; 613 char process_libusb = 0; 614 615 r = libusb_get_next_timeout(ctx, &tv); 616 if (r == 1 && tv.tv_sec == 0 && tv.tv_usec == 0) 617 { 618 r = libusb_handle_events_timeout(ctx, &tv); 619 } 620 621 delay = libusb_delay = tv.tv_sec * 1000 + tv.tv_usec; 622 if (delay <= 0 || delay > timeout) 623 { 624 delay = timeout; 625 } 626 627 CHECK_NEGATIVE(poll(fds, nfds, delay)); 628 629 process_libusb = (r == 0 && delay == libusb_delay); 630 631 for (i = 0; i < nfds; ++i) 632 { 633 if (fds[i].fd == tap_fd) { 634 if (fds[i].revents) 635 { 636 CHECK_NEGATIVE(read_tap()); 637 } 638 continue; 639 } 640 process_libusb |= fds[i].revents; 641 } 642 643 if (process_libusb) 644 { 645 struct timeval tv = {.tv_sec = 0, .tv_usec = 0}; 646 CHECK_NEGATIVE(libusb_handle_events_timeout(ctx, &tv)); 647 } 648 649 return 0; 650} 651 652/* handle events until timeout is reached or all of the events in event_mask happen */ 653static int process_events_by_mask(int timeout, unsigned int event_mask) 654{ 655 struct timeval start, curr; 656 int r; 657 int delay = timeout; 658 659 CHECK_NEGATIVE(gettimeofday(&start, NULL)); 660 661 wd_status.info_updated &= ~event_mask; 662 663 while ((event_mask == 0 || (wd_status.info_updated & event_mask) != event_mask) && delay >= 0) { 664 long a; 665 666 CHECK_NEGATIVE(process_events_once(delay)); 667 668 if (device_disconnected) { 669 if (dbus_use) dbus_conn_info_send(WS_DEV_NOT_FOUND); 670 exit_release_resources(0); 671 } 672 673 CHECK_NEGATIVE(gettimeofday(&curr, NULL)); 674 675 a = (curr.tv_sec - start.tv_sec) * 1000 + (curr.tv_usec - start.tv_usec) / 1000; 676 delay = timeout - a; 677 } 678 679 wd_status.info_updated &= ~event_mask; 680 681 return (delay > 0) ? delay : 0; 682} 683 684int alloc_fds() 685{ 686 int i; 687 const struct libusb_pollfd **usb_fds = libusb_get_pollfds(ctx); 688 689 if (!usb_fds) 690 { 691 return -1; 692 } 693 694 nfds = 0; 695 while (usb_fds[nfds]) 696 { 697 nfds++; 698 } 699 if (tap_fd != -1) { 700 nfds++; 701 } 702 703 if(fds != NULL) { 704 free(fds); 705 } 706 707 fds = (struct pollfd*)calloc(nfds, sizeof(struct pollfd)); 708 for (i = 0; usb_fds[i]; ++i) 709 { 710 fds[i].fd = usb_fds[i]->fd; 711 fds[i].events = usb_fds[i]->events; 712 set_coe(usb_fds[i]->fd); 713 } 714 if (tap_fd != -1) { 715 fds[i].fd = tap_fd; 716 fds[i].events = POLLIN; 717 fds[i].revents = 0; 718 } 719 720 free(usb_fds); 721 722 return 0; 723} 724 725void cb_add_pollfd(int fd, short events, void *user_data) 726{ 727 alloc_fds(); 728} 729 730void cb_remove_pollfd(int fd, void *user_data) 731{ 732 alloc_fds(); 733} 734 735static void dm_cmd(char *cmd) 736{ 737 unsigned char req_data[MAX_PACKET_LEN]; 738 int len; 739 len = fill_dm_cmd_req(req_data, cmd); 740 set_data(req_data, len); 741} 742 743static void DL_xml_image() 744{ 745 unsigned char req_data[MAX_PACKET_LEN]; 746 unsigned char data[0x400]; 747 int len, data_len, offset, size; 748 int r; 749 750 r = libusb_init(&ctx); 751 if (r < 0) { 752 wmlog_msg(0, "failed to initialise libusb"); 753 exit(1); 754 } 755 756 get_wimax_device(); 757 alloc_transfers(); 758 759 wmlog_msg(2, "Continuous async read start..."); 760 CHECK_DISCONNECTED(libusb_submit_transfer(req_transfer)); 761 762 fseek(xml_file, 0L, SEEK_END); 763 size = ftell(xml_file); 764 wmlog_msg(0, "XML Image size: %d",size); 765 fseek(xml_file, 0L, SEEK_SET); 766 767 if (dbus_use) dbus_conn_info_send(WS_DL_XML_START); 768 offset = 0; 769 while (offset != 0xffffffff) 770 { 771 data_len = fread(data, 1, 0x400, xml_file); 772 if (data_len == 0) 773 { 774 if (!feof(xml_file)) 775 wmlog_msg(0, "bad EOF"); 776 offset = 0xffffffff; 777 if (dbus_use) dbus_percent_info_send(0x0100, 100); 778 } 779 else 780 { 781 if (dbus_use) dbus_percent_info_send(0x0100, offset * 100 / size); 782 } 783 len = fill_image_dl_req(req_data, 0x0100, offset, data, data_len); 784// wmlog_msg(0, "percent %d",offset * 100 / size); 785 offset += data_len; 786 set_data(req_data, len); 787 process_events_by_mask(500, WDS_CERT); 788 } 789 if (dbus_use) dbus_conn_info_send(WS_DL_XML_END); 790 fclose(xml_file); 791 792 dm_cmd("reboot"); 793 794 exit_release_resources(1); 795} 796 797 798static 799void AES_cbc_decrypt(uint8_t *shakey, uint8_t *inbuf, uint8_t *outbuf) 800{ 801 unsigned char iv[16] = {0x43,0x6c,0x61,0x72,0x6b,0x4a,0x4a,0x61,0x6e,0x67,0x00,0x00,0x00,0x00,0x00,0x00}; //ClarkJJang 802 803 AES_KEY aeskey; 804 805 AES_set_decrypt_key(shakey, 24*8, &aeskey); //192 806 807 AES_cbc_encrypt(inbuf, outbuf, 16, &aeskey, iv, AES_DECRYPT); 808} 809 810 811static 812int decrypt_data(unsigned char *buf, unsigned char *outbuf, int len) 813{ 814 int i, dec_buf_len; 815 uint8_t key_sha[0x18]; 816 uint8_t dec_buf[len]; 817 818 memset(key_sha,0x00,sizeof(key_sha)); 819 memset(dec_buf,0x00,sizeof(dec_buf)); 820 821 SHA1(wd_status.mac, 6, key_sha); 822 823 for (i = 0; i < (len / 16); i++) 824 AES_cbc_decrypt(key_sha, buf + 16 * i, dec_buf + 16 * i); 825 dec_buf_len = (dec_buf[0] << 24) + (dec_buf[1] << 16) + (dec_buf[2] << 8) + dec_buf[3]; 826 memcpy(outbuf, dec_buf + 4, dec_buf_len); 827 828 wmlog_msg(2, "Decrypted size is %d bytes.", dec_buf_len); 829 return dec_buf_len; 830} 831 832 833static 834int extract_cert(unsigned char *buf, int len, char *path) 835{ 836 int dec_buf_len, gz_len; 837 char gz_path[0x100]; //, pem_path[0x100] 838 uint8_t dec_buf[len], gz_buf[MAX_PACKET_LEN]; 839 FILE *fp; 840 voidp gz; 841 842 memset(dec_buf,0x00,sizeof(dec_buf)); 843 844 dec_buf_len = decrypt_data(buf, dec_buf, len); 845 wmlog_msg(2, "Cert decrypted"); 846 847 sprintf(gz_path,"%s.gz", path); 848 fp=fopen((char *)gz_path, "wb"); 849 if (fp == NULL) 850 return errno; 851 fwrite(dec_buf, 1, dec_buf_len, fp); //dec_buf + 4 852 fclose(fp); 853 854 gz = gzopen(gz_path, "rb"); 855 if (gz == NULL) 856 return errno; 857 gz_len = gzread(gz, gz_buf, sizeof(gz_buf)); 858 gzclose(gz); 859 remove(gz_path); 860 861 wmlog_msg(2, "Extracted cert size is %d bytes.", gz_len); 862 863 fp=fopen((char *)path, "ab"); 864 if (fp == NULL) 865 return errno; 866 fwrite(gz_buf,1,gz_len,fp); 867 fclose(fp); 868 869 return 0; 870} 871 872 873static 874int get_nv_data(short code, unsigned char *buf) 875{ 876 unsigned char req_data[MAX_PACKET_LEN]; 877 int len, data_len, buf_len = 0; 878 879 memset(wd_status.cert, 0, sizeof(wd_status.cert)); 880 881 len = fill_get_data_req_start(req_data, code); 882 set_data(req_data, len); 883 884 process_events_by_mask(2000, WDS_CERT); 885 886 while(1) 887 { 888 if( ((wd_status.cert[0] << 8) + wd_status.cert[1]) == code ) 889 { 890 if (wd_status.cert[2] != 0xff) 891 { 892 data_len = (wd_status.cert_buf[0] << 8) + wd_status.cert_buf[1]; 893 894 memcpy(buf+buf_len,wd_status.cert_buf+2,data_len); 895 buf_len += data_len; 896 897 len = fill_get_data_req_step(req_data, code, buf_len); 898 set_data(req_data, len); 899 900 process_events_by_mask(2000, WDS_CERT); 901 } 902 else break; 903 } 904 else 905 break; 906 } 907 908 return buf_len; 909} 910 911 912static 913void get_cert() 914{ 915 int r, i; 916 char path[0x100]; 917 sprintf(path,CONF_DIR"/%02x%02x%02x%02x%02x%02x", wd_status.mac[0], wd_status.mac[1], \ 918 wd_status.mac[2], wd_status.mac[3], wd_status.mac[4], wd_status.mac[5]); 919 920 r = mkdir(path,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 921 if (r) 922 { 923 if (errno != EEXIST) //17 924 return; 925 } 926 927 for (i = 0x0101; i <= 0x0106; i++) 928 { 929 if ( (i == 0x0105 && wd_status.config->use_nv == 1) || 930 (i == 0x0101 && wd_status.config->cert_nv == 1 && wd_status.config->dev_cert_null == 0) || 931 (i != 0x0101 && i != 0x0105 && wd_status.config->cert_nv == 1 && wd_status.config->ca_cert_null == 0) ) 932 { 933 unsigned char data[MAX_PACKET_LEN]; 934 int data_len; 935 data_len = get_nv_data(i, data); 936 if (data_len != 0) 937 { 938 939 switch (i) { 940 case 0x0101: 941 { 942 free(wd_status.config->client_cert); 943 free(wd_status.config->private_key); 944 wd_status.config->client_cert = NULL; 945 wd_status.config->private_key = NULL; 946 wd_status.config->client_cert = (unsigned char *)malloc(strlen(path)+13); 947 sprintf((char *)wd_status.config->client_cert,"%s/client_cert.pem",path); 948 wd_status.config->private_key = (unsigned char *)strdup((char *)wd_status.config->client_cert); 949 r = extract_cert(data, data_len, (char *)wd_status.config->client_cert); 950 if(r) { 951 free(wd_status.config->client_cert); 952 free(wd_status.config->private_key); 953 wd_status.config->client_cert = NULL; 954 wd_status.config->private_key = NULL; 955 } 956 break; 957 } 958 break; 959 case 0x0102: 960 case 0x0103: 961 case 0x0104: 962 case 0x0106: 963 { 964 free(wd_status.config->ca_cert); 965 wd_status.config->ca_cert = NULL; 966 wd_status.config->ca_cert = (unsigned char *)malloc(strlen(path)+13); 967 sprintf((char *)wd_status.config->ca_cert,"%s/root_ca.pem",path); 968 r = extract_cert(data, data_len, (char *)wd_status.config->ca_cert); 969 if(r) { 970 free(wd_status.config->ca_cert); 971 wd_status.config->ca_cert = NULL; 972 } 973 break; 974 } 975 case 0x0105: 976 { 977 data_len = decrypt_data(data, data, data_len); 978 if(data_len) { 979 int j; 980 for (j=0; j < data_len;) 981 { 982 int id, id_len; 983 id = data[j]; 984 id_len = (data[j+1] << 8) + data[j+2]; 985 if(id_len) 986 { 987 char str[id_len+1]; 988 str[id_len] = '\0'; 989 memcpy(str, data+j+3, id_len); 990// wmlog_msg(2, "id: %d String: %s", id, str); 991 switch (id) { 992 case 0x01: 993 free(wd_status.config->anonymous_identity); 994 wd_status.config->anonymous_identity = NULL; 995 wd_status.config->anonymous_identity = (unsigned char *)strdup(str); 996 wd_status.config->anonymous_identity_len = id_len; 997 break; 998 case 0x02: 999 if (wd_status.config->cert_nv == 1 && 1000 wd_status.config->dev_cert_null == 0) { 1001 free(wd_status.config->private_key_passwd); 1002 wd_status.config->private_key_passwd = NULL; 1003 wd_status.config->private_key_passwd = (unsigned char *)strdup(str); 1004 } 1005 break; 1006 case 0x03: 1007 free(wd_status.config->identity); 1008 wd_status.config->identity = NULL; 1009 wd_status.config->identity = (unsigned char *)strdup(str); 1010 wd_status.config->identity_len = id_len; 1011 break; 1012 case 0x04: 1013 free(wd_status.config->password); 1014 wd_status.config->password = NULL; 1015 wd_status.config->password = (unsigned char *)strdup(str); 1016 wd_status.config->password_len = id_len; 1017 break; 1018 default: 1019 wmlog_msg(2, "Unknown EAP param from NV # %02x", id); 1020 break; 1021 } 1022 } 1023 j += id_len + 3; 1024 } 1025 } 1026 break; 1027 } 1028 } 1029 1030 } 1031 } 1032 } 1033} 1034 1035 1036static int init(void) 1037{ 1038 unsigned char req_data[MAX_PACKET_LEN]; 1039 int len; 1040 int r; 1041 1042 alloc_transfers(); 1043 1044 wmlog_msg(2, "Continuous async read start..."); 1045 CHECK_DISCONNECTED(libusb_submit_transfer(req_transfer)); 1046 1047 len = fill_rf_off_req(req_data); 1048 set_data(req_data, len); 1049 1050 process_events_by_mask(2000, WDS_RF_STATE); 1051 1052 len = fill_debug_req(req_data); //mode normal or test 1053 set_data(req_data, len); 1054 1055 len = fill_string_info_req(req_data); 1056 set_data(req_data, len); 1057 1058 process_events_by_mask(500, WDS_CHIP | WDS_FIRMWARE); 1059 1060 wmlog_msg(1, "Chip info: %s", wd_status.chip); 1061 wmlog_msg(1, "Firmware info: %s", wd_status.firmware); 1062 1063 if(wd_status.nspid == 0) { 1064 len = fill_get_nspid_req(req_data); 1065 set_data(req_data, len); 1066 process_events_by_mask(500, WDS_NSPID); 1067 } 1068 wmlog_msg(1, "H-NSPID: 0x%06x", wd_status.nspid); 1069 1070 len = fill_mac_req(req_data); 1071 set_data(req_data, len); 1072 1073 process_events_by_mask(500, WDS_MAC); 1074 1075 wmlog_msg(1, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", wd_status.mac[0], wd_status.mac[1], wd_status.mac[2], wd_status.mac[3], wd_status.mac[4], wd_status.mac[5]); 1076 1077 if (dbus_use) dbus_dev_info_send(); 1078 1079 len = fill_rf_on_req(req_data); 1080 set_data(req_data, len); 1081 1082 process_events_by_mask(20000, WDS_RF_STATE); 1083 1084 wmlog_msg(2, "RF ON."); 1085 1086 get_cert(); 1087 1088 return 0; 1089} 1090 1091static int scan_loop(void) 1092{ 1093 unsigned char req_data[MAX_PACKET_LEN]; 1094 int len; 1095 int r; 1096 1097 while (1) 1098 { 1099 if (wd_status.link_status == 0) { 1100 1101 if_down(); 1102 1103 if (wd_status.config->use_pkm == 1){ 1104 len = fill_auth_on_req(req_data); 1105 set_data(req_data, len); 1106 } 1107 1108 if (dbus_use && wd_status.network_status == 0) dbus_conn_info_send(WS_SCAN); 1109 wmlog_msg(0, "Search network..."); 1110 len = fill_find_network_req(req_data, &wd_status); 1111 set_data(req_data, len); 1112 1113 while (process_events_by_mask(60000, WDS_LINK_STATUS) < 0) {;} 1114 1115 if (wd_status.link_status == 0) { 1116 if (dbus_use && wd_status.network_status == 0) dbus_conn_info_send(WS_NET_NOT_FOUND); 1117 wmlog_msg(0, "Network not found."); 1118 wd_status.network_status--; 1119 if (wd_status.network_status < 60) 1120 sleep(30); 1121 else if (wd_status.network_status < 30) 1122 sleep(15); 1123 else if (wd_status.network_status < 10) 1124 sleep(5); 1125 } else { 1126 if (dbus_use) dbus_conn_info_send(WS_NET_FOUND); 1127 wmlog_msg(0, "Network found."); 1128 wd_status.link_status = 0; 1129 wd_status.network_status = 0; 1130 len = fill_connect_req(req_data, &wd_status); 1131 set_data(req_data, len); 1132 1133 while (process_events_by_mask(100000, WDS_LINK_STATUS) < 0) {;} 1134 1135 if (wd_status.link_status == 0) { 1136 if (dbus_use) dbus_conn_info_send(WS_CON_ERR); 1137 wmlog_msg(0, "Connection error."); 1138 } else { 1139 wmlog_msg(0, "Connected to Network."); 1140 1141 wd_status.auth_info = 0; //if more then one BS found. 1142 r = 1; 1143 while ( 1 ){ 1144 process_events_by_mask(5000, WDS_AUTH_STATE); 1145 wmlog_msg(2, "Auth_state: %06x",wd_status.auth_state); 1146 1147 switch (wd_status.auth_state) { 1148 case 0x0001ff: 1149 case 0x0100ff: 1150 case 0x0101ff: 1151 case 0x0200ff: 1152 case 0x0300ff: 1153 case 0x0301ff: 1154 case 0x0400ff: 1155 case 0x0401ff: { 1156 process_events_by_mask(3000, WDS_LINK_STATUS); 1157 goto auth_loop_done; 1158 } 1159 1160 case 0x020000: { 1161 if (dbus_use) dbus_conn_info_send(WS_START_AUTH); 1162 wmlog_msg(0, "Start Authentication."); 1163 if (eap_peer_init(wd_status.config)< 0) { 1164 wmlog_msg(0, "EAP Peer init error."); 1165 break; 1166 } 1167 r = 1; 1168 wd_status.info_updated = WDS_NONE; 1169 while( r > 0) 1170 { 1171 if (process_events_by_mask(100000, WDS_EAP)) 1172 r = eap_peer_step(); 1173 else 1174 r = 0; 1175 } 1176 eap_peer_deinit(); 1177 break; 1178 } 1179 case 0x0201ff: { 1180 if (dbus_use) dbus_conn_info_send(WS_AUTH_FAILED); 1181 if (wd_status.auth_info == 0){ 1182 wmlog_msg(0, "Authentication Failed. Renewing Authentication."); 1183 } 1184 else { 1185 wmlog_msg(0, "Authentication Failed."); 1186 goto auth_loop_done; 1187 } 1188 break; 1189 } 1190 case 0x020100: { 1191 wmlog_msg(0, "Authentication Succeed."); 1192 break; 1193 } 1194 case 0x040100: { 1195 if_up(); 1196 process_events_by_mask(2000, WDS_LINK_STATUS); 1197 process_events_by_mask(2000, WDS_LINK_STATUS); 1198 goto auth_loop_done; 1199 } 1200 default: { 1201 break; 1202 } 1203 } 1204 } 1205auth_loop_done:; 1206 } 1207 } 1208 1209 } 1210 else { 1211 1212 len = fill_connection_params_req(req_data); 1213 set_data(req_data, len); 1214 1215 process_events_by_mask(500, WDS_RSSI1 | WDS_CINR1 | WDS_RSSI2 | WDS_CINR2 | WDS_TXPWR | WDS_FREQ); 1216 1217 wmlog_msg(1, "RSSI1: %d CINR1: %d TX Power: %d Frequency: %d", 1218 wd_status.rssi1, wd_status.cinr1, wd_status.txpwr, wd_status.freq); 1219 wmlog_msg(1, "RSSI2: %d CINR2: %d", 1220 wd_status.rssi2, wd_status.cinr2); 1221 1222 if (dbus_use) dbus_sig_info_send(); 1223 1224 process_events_by_mask(5000, WDS_LINK_STATUS); 1225 } 1226 } 1227 1228 return 0; 1229} 1230 1231/* print usage information */ 1232void usage(const char *progname) 1233{ 1234 printf("Usage: %s [options]\n", progname); 1235 printf("Options:\n"); 1236 printf(" -C, --cfg-file=FILE path to configuration file\n"); 1237 printf(" --dl-xml=FILE DL XML Image & exit\n"); 1238 printf(" -D, Switch device & exit\n"); 1239 printf(" -v, verbose log level (even more -vv)\n"); 1240 printf(" -p, --pid-file=FILE PID file (only for daemonize mode)\n"); 1241 printf(" -d, --daemonize daemonize after startup\n"); 1242 printf(" -V, --version print the version number\n"); 1243#ifdef WITH_DBUS 1244 printf(" --with-dbus Run with dbus support\n"); 1245#endif 1246 printf(" -h, --help display this help\n"); 1247} 1248 1249/* print version */ 1250void version() 1251{ 1252 printf("%s %s\n", "GCTwimax", get_wimax_version()); 1253} 1254 1255static void parse_args(int argc, char **argv) 1256{ 1257 while (1) 1258 { 1259 int c; 1260 /* getopt_long stores the option index here. */ 1261 int option_index = 0; 1262 static struct option long_options[] = 1263 { 1264 {"cfg-file", required_argument, 0, 'C'}, 1265 {"dl-xml", required_argument, 0, 8}, 1266 {"daemonize", no_argument, 0, 'd'}, 1267 {"pid-file", required_argument, 0, 'p'}, 1268 {"version", no_argument, 0, 'V'}, 1269#ifdef WITH_DBUS 1270 {"with-dbus", no_argument, 0, 7}, 1271#endif /* WITH_DBUS */ 1272 {"help", no_argument, 0, 'h'}, 1273 {0, 0, 0, 0} 1274 }; 1275 1276 c = getopt_long(argc, argv, "C:p:vDdVh", long_options, &option_index); 1277 /* detect the end of the options. */ 1278 if (c == -1) 1279 break; 1280 1281 switch (c) 1282 { 1283 case 'C': { 1284 conf_file = optarg; 1285 break; 1286 } 1287 case 'p': { 1288 pid_file = rel2abs_path(optarg); 1289 break; 1290 } 1291 case 'v': { 1292 inc_wmlog_level(); 1293 break; 1294 } 1295 case 'D': { 1296 int r; 1297 r = libusb_init(&ctx); 1298 if (r < 0) { 1299 wmlog_msg(0, "failed to initialise libusb"); 1300 exit(1); 1301 } 1302 switch_wimax_device(); 1303 libusb_exit(ctx); 1304 exit(1); 1305 break; 1306 } 1307 case 'd': { 1308 daemonize = 1; 1309 break; 1310 } 1311 case 'V': { 1312 version(); 1313 exit(0); 1314 break; 1315 } 1316 case 'h': { 1317 usage(argv[0]); 1318 exit(0); 1319 break; 1320 } 1321 case '?': { 1322 /* getopt_long already printed an error message. */ 1323 usage(argv[0]); 1324 exit(1); 1325 break; 1326 } 1327#ifdef WITH_DBUS 1328 case 7: { 1329 dbus_use = 1; 1330 break; 1331 } 1332#endif /* WITH_DBUS */ 1333 case 8: { 1334 xml_file = fopen(optarg, "rb"); 1335 if (xml_file == NULL){ 1336 wmlog_msg(0, "bad xml file: %s",strerror(errno)); 1337 exit(1); 1338 } 1339 break; 1340 } 1341 default: { 1342 exit(1); 1343 } 1344 } 1345 } 1346} 1347 1348static void exit_release_resources(int code) 1349{ 1350//Rewrite this part!!!!!!! 1351 if(devh != NULL && wd_status.rf_state == 0){ 1352 unsigned char req_data[MAX_PACKET_LEN]; 1353 int len; 1354 wmlog_msg(2, "RF OFF."); 1355 len = fill_rf_off_req(req_data); 1356 set_data(req_data, len); 1357 process_events_by_mask(2000, WDS_RF_STATE); 1358 } 1359 if(wd_status.config != NULL && wd_status.config->cert_nv == 1) 1360 { 1361 if(wd_status.config->ca_cert) 1362 remove((const char *)wd_status.config->ca_cert); //Delete this 1363 if(wd_status.config->client_cert) 1364 remove((const char *)wd_status.config->client_cert); 1365 } 1366 if(tap_fd >= 0) { 1367 if_down(); 1368 while (wait(NULL) > 0) {} 1369 if_release(); 1370 while (wait(NULL) > 0) {} 1371 } 1372 if(ctx != NULL) { 1373 if(req_transfer != NULL) { 1374 libusb_cancel_transfer(req_transfer); 1375 libusb_free_transfer(req_transfer); 1376 } 1377 libusb_set_pollfd_notifiers(ctx, NULL, NULL, NULL); 1378 if(fds != NULL) { 1379 free(fds); 1380 } 1381 if(devh != NULL) { 1382 libusb_release_interface(devh, 0); 1383 if (kernel_driver_active) 1384 libusb_attach_kernel_driver(devh, 0); 1385 libusb_unlock_events(ctx); 1386 libusb_close(devh); 1387 } 1388 libusb_exit(ctx); 1389 } 1390 if (pid_file) 1391 { 1392 unlink(pid_file); 1393 free(pid_file); 1394 } 1395 if(logfile != NULL) { 1396 fclose(logfile); 1397 } 1398 if (dbus_use) { 1399#ifdef WITH_DBUS 1400 DBusMessage *message; 1401 message = dbus_message_new_signal ( "/ua/org/yarx/Daemon", 1402 "ua.org.yarx.Daemon", 1403 "ErrorAndDisconnect"); 1404 dbus_message_append_args ( message, 1405 DBUS_TYPE_INVALID); 1406 dbus_connection_send (dbus_connection, message, NULL); 1407 dbus_message_unref (message); 1408#endif /* WITH_DBUS */ 1409 } 1410 if(wd_status.config) 1411 gct_config_free(wd_status.config); 1412 exit(code); 1413} 1414 1415static void sighandler_exit(int signum) { 1416 exit_release_resources(0); 1417} 1418 1419static void sighandler_wait_child(int signum) { 1420 int status; 1421 wait3(&status, WNOHANG, NULL); 1422 wmlog_msg(2, "Child exited with status %d", status); 1423} 1424 1425//////////////////////////////////////////////////////////////// 1426/////////////////////////////////////////////////////////////// 1427////////////////////////////////////////////////////////////// 1428 1429static void dbus_dev_info_send(void) { 1430#ifdef WITH_DBUS 1431 const char *chip = wd_status.chip; 1432 const char *firmware = wd_status.firmware; 1433 char _mac[18]; 1434 1435 snprintf(_mac, 18, "%02x:%02x:%02x:%02x:%02x:%02x", wd_status.mac[0], wd_status.mac[1], wd_status.mac[2], 1436 wd_status.mac[3], wd_status.mac[4], wd_status.mac[5]); 1437 1438 const char * mac = _mac; 1439 1440 DBusMessage *message; 1441 message = dbus_message_new_signal ( "/ua/org/yarx/Daemon", 1442 "ua.org.yarx.Daemon", 1443 "SendDeviceInfo"); 1444 dbus_message_append_args ( message, 1445 DBUS_TYPE_STRING, &chip, 1446 DBUS_TYPE_STRING, &firmware, 1447 DBUS_TYPE_STRING, &mac, 1448 DBUS_TYPE_INVALID); 1449 dbus_connection_send (dbus_connection, message, NULL); 1450 dbus_message_unref (message); 1451#endif /* WITH_DBUS */ 1452} 1453 1454static void dbus_sig_info_send(void) { 1455#ifdef WITH_DBUS 1456 DBusMessage *message; 1457 message = dbus_message_new_signal ( "/ua/org/yarx/Daemon", 1458 "ua.org.yarx.Daemon", 1459 "SendSignalInfo"); 1460 dbus_message_append_args ( message, 1461 DBUS_TYPE_INT16, &wd_status.rssi1, 1462 DBUS_TYPE_INT16, &wd_status.rssi2, 1463 DBUS_TYPE_INT16, &wd_status.cinr1, 1464 DBUS_TYPE_INT16, &wd_status.cinr2, 1465 DBUS_TYPE_UINT16, &wd_status.txpwr, 1466 DBUS_TYPE_UINT32, &wd_status.freq, 1467 DBUS_TYPE_INVALID); 1468 dbus_connection_send (dbus_connection, message, NULL); 1469 dbus_message_unref (message); 1470#endif /* WITH_DBUS */ 1471} 1472 1473static void dbus_bsid_info_send(void) { 1474#ifdef WITH_DBUS 1475 char _bsid[18]; 1476 snprintf(_bsid, 18, "%02x:%02x:%02x:%02x:%02x:%02x", wd_status.bsid[0], wd_status.bsid[1], wd_status.bsid[2], 1477 wd_status.bsid[3], wd_status.bsid[4], wd_status.bsid[5]); 1478 1479 const char *bsid = _bsid; 1480 1481 DBusMessage *message; 1482 message = dbus_message_new_signal ( "/ua/org/yarx/Daemon", 1483 "ua.org.yarx.Daemon", 1484 "SendBsidInfo"); 1485 dbus_message_append_args ( message, 1486 DBUS_TYPE_STRING, &bsid, 1487 DBUS_TYPE_INVALID ); 1488 dbus_connection_send (dbus_connection, message, NULL); 1489 dbus_message_unref (message); 1490#endif /* WITH_DBUS */ 1491} 1492 1493static void dbus_conn_info_send(enum wimax_state state) { 1494#ifdef WITH_DBUS 1495 DBusMessage *message; 1496 message = dbus_message_new_signal ( "/ua/org/yarx/Daemon", 1497 "ua.org.yarx.Daemon", 1498 "SendConnectionInfo"); 1499 1500 const char *msg_state = wimax_state_to_name(state); 1501 dbus_message_append_args ( message, 1502 DBUS_TYPE_INT16, &state, 1503 DBUS_TYPE_STRING, &msg_state, 1504 DBUS_TYPE_INVALID ); 1505 dbus_connection_send (dbus_connection, message, NULL); 1506 1507 dbus_message_unref (message); 1508#endif /* WITH_DBUS */ 1509} 1510 1511 1512static void dbus_percent_info_send(short code, short percent) { 1513#ifdef WITH_DBUS 1514 DBusMessage *message; 1515 message = dbus_message_new_signal ( "/ua/org/yarx/Daemon", 1516 "ua.org.yarx.Daemon", 1517 "SendPercentInfo"); 1518 dbus_message_append_args ( message, 1519 DBUS_TYPE_INT16, &code, 1520 DBUS_TYPE_INT16, &percent, 1521 DBUS_TYPE_INVALID ); 1522 dbus_connection_send (dbus_connection, message, NULL); 1523 1524 dbus_message_unref (message); 1525#endif /* WITH_DBUS */ 1526} 1527//////////////////////////////////////////////////////////////// 1528/////////////////////////////////////////////////////////////// 1529////////////////////////////////////////////////////////////// 1530 1531static 1532void gct_config_complete() 1533{ 1534 struct gct_config *config = wd_status.config; 1535 1536 if(wimax_log_level < config->wimax_verbose_level) 1537 set_wmlog_level(config->wimax_verbose_level); 1538 1539 if (strlen(config->log_file)) 1540 logfile = fopen(config->log_file, "a"); 1541 1542 if (strlen(config->event_script)) 1543 event_script = config->event_script; 1544 1545 wd_status.nspid = config->nspid; 1546 1547 if(config->use_pkm) 1548 { 1549 if(config->ca_cert_null) 1550 { 1551 free(config->ca_cert); 1552 config->ca_cert = NULL; 1553 } 1554 1555 if(config->dev_cert_null) 1556 { 1557 free(config->client_cert); 1558 free(config->private_key); 1559 free(config->private_key_passwd); 1560 config->client_cert = NULL; 1561 config->private_key = NULL; 1562 config->private_key_passwd = NULL; 1563 } 1564 1565 switch(config->eap_type) 1566 { 1567 case -1: 1568 /* Use settings only from config file*/ 1569 break; 1570 case 3: 1571 free(config->eap_methods); 1572 free(config->identity); 1573 free(config->password); 1574 free(config->phase1); 1575 free(config->phase2); 1576 config->identity = NULL; 1577 config->password = NULL; 1578 config->identity_len = 0; 1579 config->password_len = 0; 1580 config->eap_methods = calloc(2, sizeof(*config->eap_methods)); 1581 config->eap_methods[0].vendor = EAP_VENDOR_IETF; 1582 config->eap_methods[0].method = EAP_TYPE_TLS; 1583 config->phase1 = strdup("include_tls_length=1"); 1584 config->phase2 = NULL; 1585 break; 1586 case 4: 1587 free(config->eap_methods); 1588 free(config->phase1); 1589 free(config->phase2); 1590 config->eap_methods = calloc(2, sizeof(*config->eap_methods)); 1591 config->eap_methods[0].vendor = EAP_VENDOR_IETF; 1592 config->eap_methods[0].method = EAP_TYPE_TTLS; 1593 config->phase1 = NULL; 1594 config->phase2 = strdup("auth=MD5"); 1595 break; 1596 case 5: 1597 free(config->eap_methods); 1598 free(config->phase1); 1599 free(config->phase2); 1600 config->eap_methods = calloc(2, sizeof(*config->eap_methods)); 1601 config->eap_methods[0].vendor = EAP_VENDOR_IETF; 1602 config->eap_methods[0].method = EAP_TYPE_TTLS; 1603 config->phase1 = NULL; 1604 config->phase2 = strdup("auth=MSCHAPV2"); 1605 break; 1606 case 6: 1607 free(config->eap_methods); 1608 free(config->phase1); 1609 free(config->phase2); 1610 config->eap_methods = calloc(2, sizeof(*config->eap_methods)); 1611 config->eap_methods[0].vendor = EAP_VENDOR_IETF; 1612 config->eap_methods[0].method = EAP_TYPE_TTLS; 1613 config->phase1 = NULL; 1614 config->phase2 = strdup("auth=CHAP"); 1615 break; 1616 default: 1617 wmlog_msg(0,"E: EAP Type (%d) not supported yet", 1618 config->eap_type); 1619 } 1620 } 1621} 1622 1623 1624int main(int argc, char **argv) 1625{ 1626 struct sigaction sigact; 1627 int r = 1; 1628 1629 set_wmlogger(argv[0], WMLOGGER_FILE, stderr); 1630 1631 wd_status.nspid = 0; 1632 1633 parse_args(argc, argv); 1634 1635 wmlog_msg(2,"Dir %s",CONF_DIR); 1636 1637#ifdef WITH_DBUS 1638 if (dbus_use) { 1639 dbus_error_init (&dbus_error); 1640 dbus_connection = dbus_bus_get (DBUS_BUS_SESSION, &dbus_error); 1641 1642 if (dbus_connection == NULL) { 1643 wmlog_msg(0, "Failed to connect to the D-BUS: %s\n", dbus_error.message); 1644 exit(1); 1645 } 1646 } 1647#endif /* WITH_DBUS */ 1648 1649 if (xml_file) 1650 DL_xml_image(); 1651 1652 sigact.sa_handler = sighandler_exit; 1653 sigemptyset(&sigact.sa_mask); 1654 sigact.sa_flags = 0; 1655 sigaction(SIGINT, &sigact, NULL); 1656 sigaction(SIGTERM, &sigact, NULL); 1657 sigaction(SIGQUIT, &sigact, NULL); 1658 sigact.sa_handler = sighandler_wait_child; 1659 sigaction(SIGCHLD, &sigact, NULL); 1660 1661 if (daemonize) { 1662 wmlog_msg(0, "Demon"); 1663// CHECK_NEGATIVE(daemon(0, 0)); 1664 if(daemon(0, 0)) 1665 exit(1); 1666 if (pid_file) { 1667 FILE *f = fopen(pid_file, "w"); 1668 if (f) { 1669 fprintf(f, "%u\n", getpid()); 1670 fclose(f); 1671 } 1672 } 1673 } 1674 1675 wd_status.rf_state = 1; // RF OFF 1676 wd_status.network_status = 0; 1677 wd_status.config = gct_config_read(conf_file); //conf_file 1678 if (!wd_status.config){ 1679 wmlog_msg(0, "Bad config file"); 1680 exit_release_resources(1); 1681 } 1682 1683 gct_config_complete(); 1684 1685 if (logfile != NULL) { 1686 set_wmlogger(argv[0], WMLOGGER_FILE, logfile); 1687 } else if (daemonize || dbus_use) { 1688 set_wmlogger(argv[0], WMLOGGER_SYSLOG, NULL); 1689 } else { 1690 set_wmlogger(argv[0], WMLOGGER_FILE, stderr); 1691 } 1692 1693 r = libusb_init(&ctx); 1694 if (r < 0) { 1695 if (dbus_use) dbus_conn_info_send(WS_DEV_NOT_FOUND); 1696 wmlog_msg(0, "failed to initialise libusb"); 1697 exit_release_resources(1); 1698 } 1699 1700 get_wimax_device(); 1701 1702 alloc_fds(); 1703 libusb_set_pollfd_notifiers(ctx, cb_add_pollfd, cb_remove_pollfd, NULL); 1704 1705 r = init(); 1706 if (r < 0) { 1707 if (dbus_use) dbus_conn_info_send(WS_ERR_INIT_DRIVER); 1708 wmlog_msg(0, "init error %d", r); 1709 exit_release_resources(1); 1710 } 1711 1712 if_create(); 1713 cb_add_pollfd(tap_fd, POLLIN, NULL); 1714 1715 r = scan_loop(); 1716 if (r < 0) { 1717 if (dbus_use) dbus_conn_info_send(WS_ERR_INIT_DRIVER); 1718 wmlog_msg(0, "scan_loop error %d", r); 1719 exit_release_resources(1); 1720 } 1721 1722 exit_release_resources(0); 1723 return 0; 1724} 1725 1726