void show_all_active_devices(void) { int i; if (dev_list.dev_total == 0) return; dm_log(NULL, "================="); for (i = 0; i < MAX_DEVICE_NO; i++) if (dev_list.dev[i].active) show_device_info(dev_list.dev[i].idev); dm_log(NULL, "================="); }
int mc703_send_sms(IDEV *p, char *who, char *data) { /* p->send must be implemented first */ char cmd_buf[512]; int ret; /* clear sms return flag for mc703 modem */ p->private_data.mc703.sms_return = MC703_SMS_RETURN_WAIT; /* first, get the ownership of the device */ if ((ret = strlen(who)) >= MAX_MOBILE_ID_LEN) { dm_log(p, "CELLID TOO LONG in common_send_sms(), [len=%d] : %s", ret, who); goto send_sms_error; } if (strlen(data) >= 500) { dm_log(p, "DATA TOO LONG in common_send_sms(), [len=%d].", data); goto send_sms_error; } ret = snprintf(cmd_buf, 510, "AT^HCMGS=\"%s\"", who); /* send AT+HCMGS cmd */ ret = (int)p->send(p, cmd_buf, NULL, AT_MODE_LINE); if (ret != AT_RAWDATA) { dm_log(p, "SEND SMS cmd error, it's %d, should %d.", ret, AT_RAWDATA); goto send_sms_error; } sleep(1); /* send rawdata */ snprintf(cmd_buf, 510, "%s\x1A", data); ret = (int)p->send(p, cmd_buf, NULL, AT_MODE_LINE); if (ret != AT_OK) { dm_log(p, "SEND RAW DATA error, return is %d, should %d.", ret, AT_OK); goto send_sms_error; } /* send ok */ while (p->private_data.mc703.sms_return == MC703_SMS_RETURN_WAIT) { if (idev_is_sick(p)) goto send_sms_error; usleep(300000); } if (p->private_data.mc703.sms_return == MC703_SMS_RETURN_OK) { dm_log(p, "SMS sent : %s ---> %s", data, who); } else { goto send_sms_error; } return 0; send_sms_error: return -1; }
int dm_dump_memory_debug(void) { unsigned long tot = 0; struct memblock *mb; char str[32]; size_t c; if (_head) log_very_verbose("You have a memory leak:"); for (mb = _head; mb; mb = mb->next) { for (c = 0; c < sizeof(str) - 1; c++) { if (c >= mb->length) str[c] = ' '; else if (*(char *)((char *)mb->magic + c) == '\0') str[c] = '\0'; else if (*(char *)((char *)mb->magic + c) < ' ') str[c] = '?'; else str[c] = *(char *)((char *)mb->magic + c); } str[sizeof(str) - 1] = '\0'; dm_log(_LOG_INFO, mb->file, mb->line, "block %d at %p, size %" PRIsize_t "\t [%s]", mb->id, mb->magic, mb->length, str); tot += mb->length; } if (_head) log_very_verbose("%ld bytes leaked in total", tot); return 1; }
void clear_dead_modules(void) { int i; for (i = 0; i < MAX_DEVICE_NO; i++) { IDEV *p = dev_list.dev[i].idev; if (dev_list.dev[i].active && p->status == DEAD) { dm_log(NULL, "device[%d] %s type %s is dead, freeing the device.", i, p->name, dev_model[p->type].name); unregister_device(i); } } }
/* if a device is dead, use this function to unregister from device list. */ int unregister_device(int i) { IDEV *p; if (dev_list.dev[i].active == 0) return -1; /* 1. clear flags */ if (clear_in_use_flag_for_device(i)) return -2; p = dev_list.dev[i].idev; /* I don't know if it is ok or not. */ /* TOFIX: how to free a structure with mutex ? */ lock_device(p); idev_lock(p); idev_unlock(p); unlock_device(p); /* 2. shut down daemon thread */ if (pthread_cancel(dev_list.dev[i].idev->thread_id)) dm_log(NULL, "\n[VITAL ERROR] thread cancel failed. going on.\n"); /* 3. remove device structure */ dev_list.dev_total--; dev_list.dev[i].active = 0; dev_list.dev[i].during_test = 0; idev_release(p); dev_list.dev[i].idev = NULL; dm_log(NULL, "REMOVED device index %d.", i); /* done */ return 0; }
/* there are 3 steps here : 1. set related 'in_use' flag in dev_usage 2. create related data structure of the device 3. create daemon thread for the device (step 1 is done before calling register) */ int register_device(char *name, RELATED_DEV *rdev, IDEV_TYPE type) { IDEV *p_idev; int i; /* step 2 */ /* check if there is enough room */ if (dev_list.dev_total >= MAX_DEVICE_NO) return -1; i = find_empty_entry(); if (i >= 0) { /* temprarily, we only support LC6311 module */ p_idev = idev_init(name, rdev, type); if (p_idev) { /* idev_init is also ok, then update device list. */ dev_list.dev[i].active = 1; dev_list.dev[i].idev = p_idev; dev_list.dev_total++; } else { /* idev_init failed */ return -2; } } /* FIX ME */ /* temporarily, enable module as soon as possible. */ idev_set_enable(p_idev); /* step 3 */ /* create daemon thread for the device. */ if (pthread_create(&p_idev->thread_id, NULL, device_daemon, p_idev)) { /* thread creation error */ dm_log(NULL, "create thread for device [%d][%s] error.", i, name); /* free the device structure */ idev_release(p_idev); return -3; } /* all ok. */ return i; }
int main(int argc, char *argv[]) { pthread_t main_thread; /* init device list */ dev_list_init(); /* set all devices to 'not_in_use', which is 0 */ dev_usage_init(); /* start testing thread */ // pthread_create(&main_thread, NULL, single_modem_testing, NULL); while(1) { dm_log(NULL, "start to check device ..."); device_check(); sleep(1); } return 0; }
int main(int argc, char *argv[]) { RELATED_DEV rdev; IDEV *p; rdev.prefix[0] = 0x00; rdev.start_num = 1; rdev.end_num = 0; register_device("ttyUSB0", &rdev, SIM4100); if (dev_list.dev[0].active == 0) { dm_log(NULL, "error register device."); return -1; } p = dev_list.dev[0].idev; while (idev_get_status(p) != READY) sleep(1); self_test(p); return 0; }
/* there are 2 kinds of devices to remove : 1. the pidev->status == DEAD (which means that the module doesn't work) 2. device file has gone (maybe the device is disconnected) we have to take all these possibilities into consideration. */ int device_check(void) { int i, j; /* clear all 'checked' sign */ dev_usage_clear_before_check(); /* update 'checked' */ for (i = 0; i < SUPPORTED_DEVICE_PREFIX_N; i++) { for (j = dev_usage[i].start_num; j <= dev_usage[i].end_num; j++) { char dev_file[256]; snprintf(dev_file, 256, "%s%s%d", DEV_DIR, dev_usage[i].keyword, j); /* check file existance */ if (!access(dev_file, F_OK)) dev_usage[i].checked[j] = 1; } } for (i = 0; i < SUPPORTED_DEVICE_PREFIX_N; i++) { for (j = dev_usage[i].start_num; j <= dev_usage[i].end_num; j++) { if (dev_usage[i].in_use[j] == 0 && dev_usage[i].checked[j] == 1) { /* a new device file */ IDEV_TYPE type; type = get_device_type(i, j); dev_usage[i].type[j] = type; dm_log(NULL, "%s%d[%s] found.", dev_usage[i].keyword, j, dev_model[type].name); } else if (dev_usage[i].in_use[j] == 1 && dev_usage[i].checked[j] == 0) { int ret; dm_log(NULL, "%s%d removed.", dev_usage[i].keyword, j); /* a model in use is untached, try to unreg it */ if ((ret = remove_untached_device(i, j)) < 0) { /* remove error */ dm_log(NULL, "ERROR : removing device %s%d failed.[%d]", dev_usage[i].keyword, j, ret); } else { /* remove ok */ dm_log(NULL, "DETECT REMOVE device %s%d index %d.", dev_usage[i].keyword, j, ret); } } } } /* type of new discovered devices are kept in {dev_usage[*].type} */ for (i = 0; i < SUPPORTED_DEVICES; i++) { int add_device; IDEV_DEV_FILE dev_file; char dev_file_str[MAX_DEVICES_NUM_OF_SAME_PREFIX+1]; unsigned char dev_taken[MAX_DEVICES_NUM_OF_SAME_PREFIX+1]; bzero(dev_taken, sizeof(dev_taken)); /* here, we statically only check dev_usage[0], whose keyword is "ttyUSB" */ format_one_dev_file_str(dev_file_str, dev_usage[0].type, (IDEV_TYPE)i); add_device = (int)dev_model[i].device_file_adoptation(dev_file_str, dev_taken, &dev_file); if (add_device == 1) { int ret; /* here is step 1 of register_device, set all taken devices to 'in_use' */ for (j = 0; j < MAX_DEVICES_NUM_OF_SAME_PREFIX; j++) if (dev_taken[j]) dev_usage[0].in_use[j] = 1; ret = register_device(dev_file.base_device, &dev_file.related_device, (IDEV_TYPE)i); if (ret >= 0 && ret <= MAX_DEVICE_NO) dm_log(NULL, "ADD device(%d) %s as %s module.", ret, dev_file.base_device, dev_model[i].name); else dm_log(NULL, "ERROR add device %s as %s module. ret[%d].", dev_file.base_device, dev_model[i].name, ret); } } /* finally, let's see if there is any module delared dead */ clear_dead_modules(); return 0; }