--- chan_mobile.c 2008-01-17 12:07:32.000000000 +0100 +++ chan_mobile.c.my_working_499_1.4.17 2008-01-17 12:07:20.000000000 +0100 @@ -31,7 +31,7 @@ #include -ASTERISK_FILE_VERSION(__FILE__, "$Revision: 499 $") +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 451 $") #include #include @@ -176,14 +176,26 @@ static AST_LIST_HEAD_STATIC(devices, mbl_pvt); /* CLI stuff */ -static char *handle_cli_mobile_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); -static char *handle_cli_mobile_search(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); -static char *handle_cli_mobile_rfcomm(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static const char show_usage[] = +"Usage: mobile show devices\n" +" Shows the state of Bluetooth Cell / Mobile devices.\n"; + +static const char search_usage[] = +"Usage: mobile search\n" +" Searches for Bluetooth Cell / Mobile devices in range.\n"; + +static const char rfcomm_usage[] = +"Usage: mobile rfcomm command\n" +" Send command to the rfcomm port.\n"; + +static int do_show_devices(int, int, char **); +static int do_search_devices(int, int, char **); +static int do_send_rfcomm(int, int, char **); static struct ast_cli_entry mbl_cli[] = { - AST_CLI_DEFINE(handle_cli_mobile_show_devices, "Show Bluetooth Cell / Mobile devices"), - AST_CLI_DEFINE(handle_cli_mobile_search, "Search for Bluetooth Cell / Mobile devices"), - AST_CLI_DEFINE(handle_cli_mobile_rfcomm, "Send commands to the rfcomm port for debugging"), + {{"mobile", "show", "devices", NULL}, do_show_devices, "Show Bluetooth Cell / Mobile devices", show_usage}, + {{"mobile", "search", NULL}, do_search_devices, "Search for Bluetooth Cell / Mobile devices", search_usage}, + {{"mobile", "rfcomm", NULL}, do_send_rfcomm, "Send commands to the rfcomm port for debugging", rfcomm_usage}, }; /* App stuff */ @@ -244,46 +256,35 @@ .devicestate = mbl_devicestate }; -/* CLI Commands implementation */ +/* + + CLI Commands implementation + +*/ -static char *handle_cli_mobile_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) +static int do_show_devices(int fd, int argc, char **argv) { + struct mbl_pvt *pvt; char bdaddr[18]; char group[6]; -#define FORMAT1 "%-15.15s %-17.17s %-5.5s %-15.15s %-9.9s %-5.5s %-3.3s\n" - - switch (cmd) { - case CLI_INIT: - e->command = "mobile show devices"; - e->usage = - "Usage: mobile show devices\n" - " Shows the state of Bluetooth Cell / Mobile devices.\n"; - return NULL; - case CLI_GENERATE: - return NULL; - } - - if (a->argc != 3) - return CLI_SHOWUSAGE; + #define FORMAT "%-15.15s %-17.17s %-5.5s %-15.15s %-9.9s %-5.5s %-3.3s\n" - ast_cli(a->fd, FORMAT1, "ID", "Address", "Group", "Adapter", "Connected", "State", "SMS"); + ast_cli(fd, FORMAT, "ID", "Address", "Group", "Adapter", "Connected", "State", "SMS"); AST_LIST_TRAVERSE(&devices, pvt, entry) { ba2str(&pvt->addr, bdaddr); snprintf(group, 5, "%d", pvt->group); - ast_cli(a->fd, FORMAT1, pvt->id, bdaddr, group, pvt->adapter->id, pvt->connected ? "Yes" : "No", - (pvt->state == MBL_STATE_IDLE) ? "Free" : (pvt->state < MBL_STATE_IDLE) ? "Init" : "Busy", - (pvt->has_sms) ? "Yes" : "No"); - } + ast_cli(fd, FORMAT, pvt->id, bdaddr, group, pvt->adapter->id, pvt->connected?"Yes":"No", (pvt->state == MBL_STATE_IDLE)?"Free":(pvt->state < MBL_STATE_IDLE)?"Init":"Busy", (pvt->has_sms)?"Yes":"No"); + } -#undef FORMAT1 + return RESULT_SUCCESS; - return CLI_SUCCESS; } -static char *handle_cli_mobile_search(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) +static int do_search_devices(int fd, int argc, char **argv) { + struct adapter_pvt *adapter; inquiry_info *ii = NULL; int max_rsp, num_rsp; @@ -292,34 +293,19 @@ char addr[19] = {0}; char name[31] = {0}; -#define FORMAT1 "%-17.17s %-30.30s %-6.6s %-7.7s %-4.4s\n" -#define FORMAT2 "%-17.17s %-30.30s %-6.6s %-7.7s %d\n" - - switch (cmd) { - case CLI_INIT: - e->command = "mobile search"; - e->usage = - "Usage: mobile search\n" - " Searches for Bluetooth Cell / Mobile devices in range.\n"; - return NULL; - case CLI_GENERATE: - return NULL; - } - - if (a->argc != 2) - return CLI_SHOWUSAGE; + #define FORMAT2 "%-17.17s %-30.30s %-6.6s %-7.7s %-4.4s\n" + #define FORMAT3 "%-17.17s %-30.30s %-6.6s %-7.7s %d\n" /* find a free adapter */ AST_LIST_TRAVERSE(&adapters, adapter, entry) { if (!adapter->inuse) break; } - if (!adapter) { - ast_cli(a->fd, "All Bluetooth adapters are in use at this time.\n"); - return CLI_SUCCESS; + ast_cli(fd, "All Bluetooth adapters are in use at this time.\n"); + return RESULT_SUCCESS; } - + len = 8; max_rsp = 255; flags = IREQ_CACHE_FLUSH; @@ -327,63 +313,52 @@ ii = alloca(max_rsp * sizeof(inquiry_info)); num_rsp = hci_inquiry(adapter->dev_id, len, max_rsp, NULL, &ii, flags); if (num_rsp > 0) { - ast_cli(a->fd, FORMAT1, "Address", "Name", "Usable", "Type", "Port"); + ast_cli(fd, FORMAT2, "Address", "Name", "Usable", "Type", "Port"); for (i = 0; i < num_rsp; i++) { - ba2str(&(ii + i)->bdaddr, addr); + ba2str(&(ii+i)->bdaddr, addr); name[0] = 0x00; - if (hci_read_remote_name(adapter->hci_socket, &(ii + i)->bdaddr, sizeof(name) - 1, name, 0) < 0) + if (hci_read_remote_name(adapter->hci_socket, &(ii+i)->bdaddr, sizeof(name)-1, name, 0) < 0) strcpy(name, "[unknown]"); phport = sdp_search(addr, HANDSFREE_AGW_PROFILE_ID); if (!phport) hsport = sdp_search(addr, HEADSET_PROFILE_ID); else hsport = 0; - ast_cli(a->fd, FORMAT2, addr, name, (phport > 0 || hsport > 0) ? "Yes" : "No", - (phport > 0) ? "Phone" : "Headset", (phport > 0) ? phport : hsport); + ast_cli(fd, FORMAT3, addr, name, (phport > 0 || hsport > 0)?"Yes":"No", (phport > 0)?"Phone":"Headset", (phport > 0)?phport:hsport); } } else - ast_cli(a->fd, "No Bluetooth Cell / Mobile devices found.\n"); + ast_cli(fd, "No Bluetooth Cell / Mobile devices found.\n"); -#undef FORMAT1 -#undef FORMAT2 + return RESULT_SUCCESS; - return CLI_SUCCESS; } -static char *handle_cli_mobile_rfcomm(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) +static int do_send_rfcomm(int fd, int argc, char **argv) { + + struct mbl_pvt *pvt; char buf[128]; - struct mbl_pvt *pvt = NULL; - switch (cmd) { - case CLI_INIT: - e->command = "mobile rfcomm"; - e->usage = - "Usage: mobile rfcomm \n" - " Send to the rfcomm port on the device\n" - " with the specified .\n"; - return NULL; - case CLI_GENERATE: - return NULL; + if (argc != 4) { + ast_cli(fd, "You must specify the name of the device and command.\n"); + return RESULT_SUCCESS; } - if (a->argc != 4) - return CLI_SHOWUSAGE; - AST_LIST_TRAVERSE(&devices, pvt, entry) { - if (!strcmp(pvt->id, a->argv[2])) + if (!strcmp(pvt->id, argv[2])) break; } if (!pvt || !pvt->connected) { - ast_cli(a->fd, "Device %s not found.\n", a->argv[2]); - return CLI_SUCCESS; + ast_cli(fd, "Device %s not found.\n", argv[2]); + return RESULT_SUCCESS; } - snprintf(buf, sizeof(buf), "%s\r", a->argv[3]); + sprintf(buf, "%s\r", argv[3]); rfcomm_write(pvt, buf); - return CLI_SUCCESS; + return RESULT_SUCCESS; + } /* @@ -541,7 +516,7 @@ chn->writeformat = prefformat; chn->readformat = prefformat; chn->tech_pvt = pvt; - ast_channel_set_fd(chn, 0, pvt->io_pipe[0]); + chn->fds[0] = pvt->io_pipe[0]; if (state == AST_STATE_RING) chn->rings = 1; ast_string_field_set(chn, language, "en"); @@ -640,7 +615,7 @@ return -1; } - ast_debug(1, "Calling %s on %s\n", dest, ast->name); + ast_log(LOG_DEBUG, "Calling %s on %s\n", dest, ast->name); if (pvt->type == MBL_TYPE_PHONE) { ast_copy_string(pvt->dial_number, dest_num, sizeof(pvt->dial_number)); @@ -665,9 +640,10 @@ } pvt = ast->tech_pvt; - ast_debug(1, "Hanging up device %s.\n", pvt->id); + ast_log(LOG_DEBUG, "Hanging up device %s.\n", pvt->id); - ast_channel_set_fd(ast, 0, -1); + /* ast_channel_set_fd(ast, 0, -1); */ + ast->fds[0] = -1; close(pvt->io_pipe[0]); close(pvt->io_pipe[1]); @@ -728,7 +704,7 @@ if (pvt->type == MBL_TYPE_HEADSET) return 0; - ast_debug(1, "Dialed %c\n", digit); + ast_log(LOG_DEBUG, "Dialed %c\n", digit); switch(digit) { case '0': @@ -762,7 +738,7 @@ struct ast_frame *f; int r; - ast_debug(2, "*** mbl_read()\n"); + ast_log(LOG_DEBUG, "*** mbl_read()\n"); if (!pvt->owner) { return &ast_null_frame; @@ -806,7 +782,7 @@ int i, r, io_need, num_frames; char *pfr, buf[DEVICE_FRAME_SIZE]; - ast_debug(2, "*** mbl_write\n"); + ast_log(LOG_DEBUG, "*** mbl_write\n"); if (frame->frametype != AST_FRAME_VOICE) { return 0; @@ -869,7 +845,7 @@ device = ast_strdupa(S_OR(data, "")); - ast_debug(1, "Checking device state for device %s\n", device); + ast_log(LOG_DEBUG, "Checking device state for device %s\n", device); AST_LIST_TRAVERSE(&devices, pvt, entry) { if (!strcmp(pvt->id, device)) @@ -943,13 +919,13 @@ return; } - ast_debug(1, "Alignment Detection result is [%-d %-d %-d %-d]\n", pvt->alignment_samples[0], pvt->alignment_samples[1], pvt->alignment_samples[2], pvt->alignment_samples[3]); + ast_log(LOG_DEBUG, "Alignment Detection result is [%-d %-d %-d %-d]\n", pvt->alignment_samples[0], pvt->alignment_samples[1], pvt->alignment_samples[2], pvt->alignment_samples[3]); a = abs(pvt->alignment_samples[1]) + abs(pvt->alignment_samples[2]) + abs(pvt->alignment_samples[3]); a /= 3; if (a > 100) { pvt->alignment_detection_triggered = 1; - ast_debug(1, "Alignment Detection Triggered.\n"); + ast_log(LOG_DEBUG, "Alignment Detection Triggered.\n"); } else pvt->do_alignment_detection = 0; @@ -967,7 +943,7 @@ int s; if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { - ast_debug(1, "socket() failed (%d).\n", errno); + ast_log(LOG_DEBUG, "socket() failed (%d).\n", errno); return -1; } @@ -976,7 +952,7 @@ bacpy(&addr.rc_bdaddr, &src); addr.rc_channel = (uint8_t) 1; if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - ast_debug(1, "bind() failed (%d).\n", errno); + ast_log(LOG_DEBUG, "bind() failed (%d).\n", errno); close(s); return -1; } @@ -986,7 +962,7 @@ bacpy(&addr.rc_bdaddr, &dst); addr.rc_channel = remote_channel; if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - ast_debug(1, "connect() failed (%d).\n", errno); + ast_log(LOG_DEBUG, "connect() failed (%d).\n", errno); close(s); return -1; } @@ -1002,12 +978,12 @@ ssize_t num_write; int len; - ast_debug(1, "rfcomm_write() (%s) [%s]\n", pvt->id, buf); + ast_log(LOG_DEBUG, "rfcomm_write() (%s) [%s]\n", pvt->id, buf); len = strlen(buf); p = buf; while (len > 0) { if ((num_write = write(pvt->rfcomm_socket, p, len)) == -1) { - ast_debug(1, "rfcomm_write() error [%d]\n", errno); + ast_log(LOG_DEBUG, "rfcomm_write() error [%d]\n", errno); return 0; } len -= num_write; @@ -1075,6 +1051,7 @@ } } else return rlen; + } } else if (sel == 0) { /* timeout */ return 0; @@ -1097,7 +1074,7 @@ int s; if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { - ast_debug(1, "socket() failed (%d).\n", errno); + ast_log(LOG_DEBUG, "socket() failed (%d).\n", errno); return -1; } @@ -1105,7 +1082,7 @@ addr.sco_family = AF_BLUETOOTH; bacpy(&addr.sco_bdaddr, &src); if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - ast_debug(1, "bind() failed (%d).\n", errno); + ast_log(LOG_DEBUG, "bind() failed (%d).\n", errno); close(s); return -1; } @@ -1115,7 +1092,7 @@ bacpy(&addr.sco_bdaddr, &dst); if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - ast_debug(1, "sco connect() failed (%d).\n", errno); + ast_log(LOG_DEBUG, "sco connect() failed (%d).\n", errno); close(s); return -1; } @@ -1130,15 +1107,15 @@ int r; if (s == -1) { - ast_debug(2, "sco_write() not ready\n"); + ast_log(LOG_DEBUG, "sco_write() not ready\n"); return 0; } - ast_debug(2, "sco_write()\n"); + ast_log(LOG_DEBUG, "sco_write()\n"); r = write(s, buf, len); if (r == -1) { - ast_debug(2, "sco write error %d\n", errno); + ast_log(LOG_DEBUG, "sco write error %d\n", errno); return 0; } @@ -1152,15 +1129,15 @@ int r; if (s == -1) { - ast_debug(2, "sco_read() not ready\n"); + ast_log(LOG_DEBUG, "sco_read() not ready\n"); return 0; } - ast_debug(2, "sco_read()\n"); + ast_log(LOG_DEBUG, "sco_read()\n"); r = read(s, buf, len); if (r == -1) { - ast_debug(2, "sco_read() error %d\n", errno); + ast_log(LOG_DEBUG, "sco_read() error %d\n", errno); return 0; } @@ -1190,7 +1167,7 @@ port = 0; session = sdp_connect(BDADDR_ANY, &bdaddr, SDP_RETRY_IF_BUSY); if (!session) { - ast_debug(1, "sdp_connect() failed on device %s.\n", addr); + ast_log(LOG_DEBUG, "sdp_connect() failed on device %s.\n", addr); return 0; } @@ -1210,9 +1187,9 @@ sdp_record_free(sdprec); sdp_list_free(response_list, 0); } else - ast_debug(1, "No responses returned for device %s.\n", addr); + ast_log(LOG_DEBUG, "No responses returned for device %s.\n", addr); } else - ast_debug(1, "sdp_service_search_attr_req() failed on device %s.\n", addr); + ast_log(LOG_DEBUG, "sdp_service_search_attr_req() failed on device %s.\n", addr); sdp_list_free(search_list, 0); sdp_list_free(attrid_list, 0); @@ -1326,7 +1303,7 @@ s = rfcomm_read(pvt, buf, 0, t); if ((s > 0) && (buf[0] != 0x0) && (buf[0] != '\r')) { - ast_debug(1, "rfcomm_read() (%s) [%s]\n", pvt->id, buf); + ast_log(LOG_DEBUG, "rfcomm_read() (%s) [%s]\n", pvt->id, buf); switch (pvt->state) { case MBL_STATE_INIT: if (strstr(buf, "+BRSF:")) { @@ -1367,7 +1344,7 @@ sprintf(pvt->ciev_callsetup_3, "%d,3", callsetupp); if (callsetupp == 0) /* This phone has no call setup indication!! ... */ pvt->no_callsetup = 1; - ast_debug(1, "CIEV_CALL=%d CIEV_CALLSETUP=%d\n", callp, callsetupp); + ast_log(LOG_DEBUG, "CIEV_CALL=%d CIEV_CALLSETUP=%d\n", callp, callsetupp); } if (strstr(buf, "OK")) { rfcomm_write(pvt, "AT+CIND?\r"); @@ -1424,7 +1401,7 @@ case MBL_STATE_PREIDLE: /* Nothing handled here, wait for timeout, then off we go... */ break; case MBL_STATE_IDLE: - ast_debug(1, "Device %s [%s]\n", pvt->id, buf); + ast_log(LOG_DEBUG, "Device %s [%s]\n", pvt->id, buf); if (strstr(buf, "RING")) { pvt->state = MBL_STATE_RING; } else if (strstr(buf, "+CIEV:")) { @@ -1521,8 +1498,9 @@ break; case MBL_STATE_HANGUP: if (strstr(buf, "OK") || strstr(buf, pvt->ciev_call_0)) { - close(pvt->sco_socket); - pvt->sco_socket = -1; + /* commented out according to note latysheff - 12-24-07 07:27 */ + /* close(pvt->sco_socket); */ + /* pvt->sco_socket = -1; */ pvt->state = MBL_STATE_IDLE; } break; @@ -1605,7 +1583,7 @@ } else if (pvt->state == MBL_STATE_HANGUP) { if (pvt->do_hangup) { if (pvt->hangup_count == 6) { - ast_debug(1, "Device %s failed to hangup after 6 tries, disconnecting.\n", pvt->id); + ast_log(LOG_DEBUG, "Device %s failed to hangup after 6 tries, disconnecting.\n", pvt->id); monitor = 0; } rfcomm_write(pvt, "AT+CHUP\r"); @@ -1678,7 +1656,7 @@ s = rfcomm_read(pvt, buf, 0, t); if ((s > 0) && (buf[0] != 0x0) && (buf[0] != '\r')) { - ast_debug(1, "rfcomm_read() (%s) [%s]\n", pvt->id, buf); + ast_log(LOG_DEBUG, "rfcomm_read() (%s) [%s]\n", pvt->id, buf); switch (pvt->state) { case MBL_STATE_RING2: if (strstr(buf, "AT+CKPD=")) { @@ -1834,15 +1812,15 @@ return NULL; } while (1) { - ast_debug(1, "About to accept() socket.\n"); + ast_log(LOG_DEBUG, "About to accept() socket.\n"); addrlen = sizeof(struct sockaddr_sco); if ((ns = accept(adapter->sco_socket, (struct sockaddr *)&addr, &addrlen)) > -1) { - ast_debug(1, "accept()ed socket.\n"); + ast_log(LOG_DEBUG, "accept()ed socket.\n"); len = sizeof(so); getsockopt(ns, SOL_SCO, SCO_OPTIONS, &so, &len); ba2str(&addr.sco_bdaddr, saddr); - ast_debug(1, "Incoming Audio Connection from device %s MTU is %d\n", saddr, so.mtu); + ast_log(LOG_DEBUG, "Incoming Audio Connection from device %s MTU is %d\n", saddr, so.mtu); pvt = NULL; AST_LIST_TRAVERSE(&devices, pvt, entry) { @@ -1854,7 +1832,7 @@ close(pvt->sco_socket); pvt->sco_socket = ns; } else - ast_debug(1, "Could not find device for incoming Audio Connection.\n"); + ast_log(LOG_DEBUG, "Could not find device for incoming Audio Connection.\n"); } else { ast_log(LOG_ERROR, "accept() failed %d\n", errno); } @@ -1884,7 +1862,7 @@ char nadapters = 0; struct ast_flags config_flags = { 0 }; - cfg = ast_config_load(MBL_CONFIG, config_flags); + cfg = ast_config_load(MBL_CONFIG); if (!cfg) return 0; @@ -1901,7 +1879,7 @@ address = ast_variable_retrieve(cfg, cat, "address"); master = ast_variable_retrieve(cfg, cat, "forcemaster"); aligndetect = ast_variable_retrieve(cfg, cat, "alignmentdetection"); - ast_debug(1, "Loading adapter %s %s.\n", id, address); + ast_log(LOG_DEBUG, "Loading adapter %s %s.\n", id, address); if (!ast_strlen_zero(id) && !ast_strlen_zero(address)) { if ((adapter = ast_calloc(1, sizeof(*adapter)))) { ast_copy_string(adapter->id, id, sizeof(adapter->id)); @@ -1952,7 +1930,7 @@ cat = ast_category_browse(cfg, NULL); while (cat) { if (strcasecmp(cat, "general") && strcasecmp(cat, "adapter")) { - ast_debug(1, "Loading device %s.\n", cat); + ast_log(LOG_DEBUG, "Loading device %s.\n", cat); address = ast_variable_retrieve(cfg, cat, "address"); useadapter = ast_variable_retrieve(cfg, cat, "adapter"); port = ast_variable_retrieve(cfg, cat, "port"); @@ -1990,7 +1968,7 @@ if (!ast_strlen_zero(nocallsetup)) { if ((*nocallsetup == 'y') || (*nocallsetup == 'Y')) { pvt->no_callsetup = 1; - ast_debug(1, "Setting nocallsetup mode for device %s.\n", pvt->id); + ast_log(LOG_DEBUG, "Setting nocallsetup mode for device %s.\n", pvt->id); } } pvt->dsp = ast_dsp_new();