/*
 * Updates the display device page to reflect the current
 * configuration of the display device.
 */
static void display_device_setup(CtkDisplayDevice *ctk_object)
{
    CtrlTarget *ctrl_target = ctk_object->ctrl_target;

    /* Disable the reset button here and allow the controls below to (re)enable
     * it if need be,.
     */
    gtk_widget_set_sensitive(ctk_object->reset_button, FALSE);

    update_display_enabled_flag(ctrl_target, &ctk_object->display_enabled);

    /* Update info */

    update_device_info(ctk_object);

    ctk_edid_setup(CTK_EDID(ctk_object->edid));

    /* Update controls */

    ctk_color_controls_setup(CTK_COLOR_CONTROLS(ctk_object->color_controls));

    ctk_dithering_controls_setup
        (CTK_DITHERING_CONTROLS(ctk_object->dithering_controls));

    ctk_image_sliders_setup(CTK_IMAGE_SLIDERS(ctk_object->image_sliders));

} /* display_device_setup() */
Example #2
0
static int
is_connection_established(const HANDLE hRadio, BLUETOOTH_DEVICE_INFO *device_info)
{
    /* NOTE: Sometimes the Bluetooth connection appears to be established
     *       even though the Move decided that it is not really connected
     *       yet. That is why we cannot simply stop trying to connect after
     *       the first successful check. Instead, we require a minimum
     *       number of successive successful checks to be sure.
     */

    unsigned int i;
    for (i = 0; i < CONN_CHECK_NUM_TRIES; i++) {
        /* read device info again to check if we have a connection */
        if (update_device_info(hRadio, device_info) != 0) {
            return 0;
        }

        if (device_info->fConnected && device_info->fRemembered && is_hid_service_enabled(hRadio, device_info)) {
        } else {
            return 0;
        }

        Sleep(CONN_CHECK_DELAY);
    }

    return 1;
}
Example #3
0
void monitor_start(struct monitor* mon)
{
  while(mon->active) {
    update_device_info(mon);

    usleep(mon->update_interval * 1000);
  }

}
static struct device_info *info_device (int unitnum, struct device_info *di, int quick)
{
	struct dev_info_spti *dispti = unitcheck (unitnum);
	if (!dispti)
		return NULL;
	if (!quick)
		update_device_info (unitnum);
	dispti->di.open = dispti->open;
	memcpy (di, &dispti->di, sizeof (struct device_info));
	return di;
}
static struct device_info *info_device (int unitnum, struct device_info *di, int quick, int session)
{
	struct dev_info_ioctl *ciw = unitcheck (unitnum);
	if (!ciw)
		return 0;
	if (!quick)
		update_device_info (unitnum);
	ciw->di.open = ciw->open;
	memcpy (di, &ciw->di, sizeof (struct device_info));
	return di;
}
static int ioctl_ismedia (int unitnum, int quick)
{
	struct dev_info_ioctl *ciw = unitisopen (unitnum);
	if (!ciw)
		return -1;
	if (quick) {
		return ciw->di.media_inserted;
	}
	update_device_info (unitnum);
	return ismedia (ciw, unitnum);
}
static int open_scsi_device2 (struct dev_info_spti *di, int unitnum)
{
	HANDLE h;
	TCHAR *dev;

	if (di->bus >= 0) {
		dev = xmalloc (TCHAR, 100);
		_stprintf (dev, L"\\\\.\\Scsi%d:", di->bus);
	} else {
		dev = my_strdup (di->drvpath);
	}
	if (!di->scsibuf)
		di->scsibuf = (uae_u8*)VirtualAlloc (NULL, DEVICE_SCSI_BUFSIZE, MEM_COMMIT, PAGE_READWRITE);
	h = CreateFile(dev,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
	di->handle = h;
	if (h == INVALID_HANDLE_VALUE) {
		write_log (L"SPTI: failed to open unit %d err=%d ('%s')\n", unitnum, GetLastError (), dev);
	} else {
		uae_u8 inqdata[INQUIRY_SIZE + 1] = { 0 };
		checkcapabilities (di);
		if (!inquiry (di, unitnum, inqdata)) {
			write_log (L"SPTI: inquiry failed unit %d ('%s':%d:%d:%d:%d)\n", unitnum, dev,
				di->bus, di->path, di->target, di->lun);
			close_scsi_device2 (di);
			xfree (dev);
			return 0;
		}
		inqdata[INQUIRY_SIZE] = 0;
		di->name = my_strdup_ansi ((char*)inqdata + 8);
		if (di->type == INQ_ROMD) {
			di->mediainserted = mediacheck (di, unitnum);
			write_log (L"SPTI: unit %d (%c:\\) opened [%s], %s, '%s'\n",
				unitnum, di->drvletter ? di->drvletter : '*',
				di->isatapi ? L"ATAPI" : L"SCSI",
				di->mediainserted ? L"media inserted" : L"drive empty",
				di->name);
		} else {
			write_log (L"SPTI: unit %d, type %d, '%s'\n",
				unitnum, di->type, di->name);
		}
		di->inquirydata = xmalloc (uae_u8, INQUIRY_SIZE);
		memcpy (di->inquirydata, inqdata, INQUIRY_SIZE);
		xfree (dev);
		di->open = true;
		update_device_info (unitnum);
		if (di->type == INQ_ROMD)
			blkdev_cd_change (unitnum, di->drvletter ? di->drvlettername : di->name);
		return 1;
	}
	xfree (dev);
	return 0;
}
Example #8
0
void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
    app_gap_cb_t *p_dev = &m_dev_info;
    char bda_str[18];
    char uuid_str[37];

    switch (event) {
    case ESP_BT_GAP_DISC_RES_EVT: {
        update_device_info(param);
        break;
    }
    case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: {
        if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) {
            ESP_LOGI(GAP_TAG, "Device discovery stopped.");
            if ( (p_dev->state == APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE ||
                    p_dev->state == APP_GAP_STATE_DEVICE_DISCOVERING)
                    && p_dev->dev_found) {
                p_dev->state = APP_GAP_STATE_SERVICE_DISCOVERING;
                ESP_LOGI(GAP_TAG, "Discover services ...");
                esp_bt_gap_get_remote_services(p_dev->bda);
            }
        } else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) {
            ESP_LOGI(GAP_TAG, "Discovery started.");
        }
        break;
    }
    case ESP_BT_GAP_RMT_SRVCS_EVT: {
        if (memcmp(param->rmt_srvcs.bda, p_dev->bda, ESP_BD_ADDR_LEN) == 0 &&
                p_dev->state == APP_GAP_STATE_SERVICE_DISCOVERING) {
            p_dev->state = APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE;
            if (param->rmt_srvcs.stat == ESP_BT_STATUS_SUCCESS) {
                ESP_LOGI(GAP_TAG, "Services for device %s found",  bda2str(p_dev->bda, bda_str, 18));
                for (int i = 0; i < param->rmt_srvcs.num_uuids; i++) {
                    esp_bt_uuid_t *u = param->rmt_srvcs.uuid_list + i;
                    ESP_LOGI(GAP_TAG, "--%s", uuid2str(u, uuid_str, 37));
                    // ESP_LOGI(GAP_TAG, "--%d", u->len);
                }
            } else {
                ESP_LOGI(GAP_TAG, "Services for device %s not found",  bda2str(p_dev->bda, bda_str, 18));
            }
        }
        break;
    }
    case ESP_BT_GAP_RMT_SRVC_REC_EVT:
    default: {
        ESP_LOGI(GAP_TAG, "event: %d", event);
        break;
    }
    }
    return;
}
void win32_spti_media_change (TCHAR driveletter, int insert)
{
	for (int i = 0; i < total_devices; i++) {
		struct dev_info_spti *di = &dev_info[i];
		if (di->drvletter == driveletter && di->mediainserted != insert) {
			write_log (L"SPTI: media change %c %d\n", dev_info[i].drvletter, insert);
			di->mediainserted = insert;
			int unitnum = getunitnum (di);
			if (unitnum >= 0) {
				update_device_info (unitnum);
				scsi_do_disk_change (unitnum, insert, NULL);
				blkdev_cd_change (unitnum, di->drvletter ? di->drvlettername : di->name);
			}
		}
	}
}
Example #10
0
bool win32_ioctl_media_change (TCHAR driveletter, int insert)
{
	for (int i = 0; i < total_devices; i++) {
		struct dev_info_ioctl *ciw = &ciw32[i];
		if (ciw->drvletter == driveletter && ciw->di.media_inserted != insert) {
			write_log (_T("IOCTL: media change %s %d\n"), ciw->drvlettername, insert);
			ciw->di.media_inserted = insert;
			int unitnum = getunitnum (ciw);
			if (unitnum >= 0) {
				update_device_info (unitnum);
				scsi_do_disk_change (unitnum, insert, NULL);
				filesys_do_disk_change (unitnum, insert != 0);
				blkdev_cd_change (unitnum, ciw->drvlettername);
				return true;
			}
		}
	}
	return false;
}
Example #11
0
static void
handle_windows8_and_later(const BLUETOOTH_ADDRESS *move_addr, const BLUETOOTH_ADDRESS *radio_addr, const HANDLE hRadio)
{
    unsigned int scan = 0;
    int connected = 0;
    while (!connected) {
        BLUETOOTH_DEVICE_INFO device_info;
        if (get_bluetooth_device_info(hRadio, move_addr, &device_info, scan == 0) != 0) {
            WINPAIR_DEBUG("No Bluetooth device found matching the given address");
        } else {
            if (is_move_motion_controller(&device_info)) {
                WINPAIR_DEBUG("Found Move Motion Controller matching the given address");

                unsigned int conn_try;
                for (conn_try = 1; conn_try <= CONN_RETRIES; conn_try++) {
                    WINPAIR_DEBUG("Connection try %d/%d", conn_try, CONN_RETRIES);

                    if (update_device_info(hRadio, &device_info) != 0) {
                        break;
                    }

                    if (device_info.fConnected) {
                        /* Windows 8 (and later) seems to require manual help with setting up
                         * the device in the registry.
                         */
                        WINPAIR_DEBUG("Patching the registry ...");
                        if (patch_registry(move_addr, radio_addr) != 0) {
                            WINPAIR_DEBUG("Failed to patch the registry");
                        }

                        /* enable HID service only if necessary */
                        WINPAIR_DEBUG("Checking HID service ...");
                        if (!is_hid_service_enabled(hRadio, &device_info)) {
                            WINPAIR_DEBUG("Enabling HID service ...");
                            GUID service = HumanInterfaceDeviceServiceClass_UUID;
                            DWORD result = BluetoothSetServiceState(hRadio, &device_info, &service, BLUETOOTH_SERVICE_ENABLE);
                            if (result != ERROR_SUCCESS) {
                                WINPAIR_DEBUG("Failed to enable HID service");
                            }

                            WINPAIR_DEBUG("Patching the registry ...");
                            if (patch_registry(move_addr, radio_addr) != 0) {
                                WINPAIR_DEBUG("Failed to patch the registry");
                            }
                        }

                        WINPAIR_DEBUG("Verifying successful connection ...");
                        if (is_connection_established(hRadio, &device_info)) {
                            /* if we have a connection, stop trying to connect this device */
                            printf("Connection verified.\n");
                            connected = 1;
                            break;
                        }
                    }

                    Sleep(CONN_DELAY);
                }

                if(!device_info.fConnected) {
                    BluetoothRemoveDevice(&(device_info.Address));
                    WINPAIR_DEBUG("Device removed, starting all over again");
                }
            } else {
                WINPAIR_DEBUG("Bluetooth device matching the given address is not a Move Motion Controller");
            }
        }

        Sleep(SLEEP_BETWEEN_SCANS);
        scan = (scan + 1) % BT_SCAN_NEW_INQUIRY;
    }
}
Example #12
0
int send_ra(struct Interface *iface, struct in6_addr *dest)
{
	struct in6_addr all_hosts_addr = {{{0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}};
	struct nd_router_advert *radvert;
	struct AdvPrefix *prefix;
	struct AdvRoute *route;
	struct AdvRDNSS *rdnss;
	struct AdvDNSSL *dnssl;
	struct AdvLowpanCo *lowpanco;
	struct AdvAbro *abroo;
	struct timespec time_now;
	int64_t secs_since_last_ra;
	char addr_str[INET6_ADDRSTRLEN];

	unsigned char buff[MSG_SIZE_SEND];
	size_t buff_dest = 0;
	size_t len = 0;
	ssize_t err;

	update_device_info(iface);

	/* First we need to check that the interface hasn't been removed or deactivated */
	if (check_device(iface) < 0) {
		if (iface->IgnoreIfMissing)	/* a bit more quiet warning message.. */
			dlog(LOG_DEBUG, 4, "interface %s does not exist, ignoring the interface", iface->Name);
		else {
			flog(LOG_WARNING, "interface %s does not exist, ignoring the interface", iface->Name);
		}
		iface->HasFailed = 1;
		/* not really a 'success', but we need to schedule new timers.. */
		return 0;
	} else {
		/* check_device was successful, act if it has failed previously */
		if (iface->HasFailed == 1) {
			flog(LOG_WARNING, "interface %s seems to have come back up, trying to reinitialize", iface->Name);
			iface->HasFailed = 0;
			/*
			 * return -1 so timer_handler() doesn't schedule new timers,
			 * reload_config() will kick off new timers anyway.  This avoids
			 * timer list corruption.
			 */
			reload_config();
			return -1;
		}
	}

	/* Make sure that we've joined the all-routers multicast group */
	if (!disableigmp6check && check_allrouters_membership(iface) < 0)
		flog(LOG_WARNING, "problem checking all-routers membership on %s", iface->Name);

	if (!iface->AdvSendAdvert) {
		dlog(LOG_DEBUG, 2, "AdvSendAdvert is off for %s", iface->Name);
		return 0;
	}

	dlog(LOG_DEBUG, 3, "sending RA on %s", iface->Name);

	if (dest == NULL) {
		dest = (struct in6_addr *)&all_hosts_addr;
		clock_gettime(CLOCK_MONOTONIC, &iface->last_multicast);
	}

	clock_gettime(CLOCK_MONOTONIC, &time_now);
	secs_since_last_ra = timespecdiff(&time_now, &iface->last_ra_time) / 1000;
	if (secs_since_last_ra < 0) {
		secs_since_last_ra = 0;
		flog(LOG_WARNING, "clock_gettime(CLOCK_MONOTONIC) went backwards!");
	}
	iface->last_ra_time = time_now;

	memset(buff, 0, sizeof(buff));
	radvert = (struct nd_router_advert *)buff;

	send_ra_inc_len(&len, sizeof(struct nd_router_advert));

	radvert->nd_ra_type = ND_ROUTER_ADVERT;
	radvert->nd_ra_code = 0;
	radvert->nd_ra_cksum = 0;

	radvert->nd_ra_curhoplimit = iface->AdvCurHopLimit;
	radvert->nd_ra_flags_reserved = (iface->AdvManagedFlag) ? ND_RA_FLAG_MANAGED : 0;
	radvert->nd_ra_flags_reserved |= (iface->AdvOtherConfigFlag) ? ND_RA_FLAG_OTHER : 0;
	/* Mobile IPv6 ext */
	radvert->nd_ra_flags_reserved |= (iface->AdvHomeAgentFlag) ? ND_RA_FLAG_HOME_AGENT : 0;

	if (iface->cease_adv) {
		radvert->nd_ra_router_lifetime = 0;
	} else {
		/* if forwarding is disabled, send zero router lifetime */
		radvert->nd_ra_router_lifetime = !check_ip6_forwarding()? htons(iface->AdvDefaultLifetime) : 0;
	}
	radvert->nd_ra_flags_reserved |= (iface->AdvDefaultPreference << ND_OPT_RI_PRF_SHIFT) & ND_OPT_RI_PRF_MASK;

	radvert->nd_ra_reachable = htonl(iface->AdvReachableTime);
	radvert->nd_ra_retransmit = htonl(iface->AdvRetransTimer);

	prefix = iface->AdvPrefixList;

	/*
	 *      add prefix options
	 */

	while (prefix) {
		if (prefix->enabled && (!prefix->DecrementLifetimesFlag || prefix->curr_preferredlft > 0)) {
			struct nd_opt_prefix_info *pinfo;

			pinfo = (struct nd_opt_prefix_info *)(buff + len);

			send_ra_inc_len(&len, sizeof(*pinfo));

			pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
			pinfo->nd_opt_pi_len = 4;
			pinfo->nd_opt_pi_prefix_len = prefix->PrefixLen;

			pinfo->nd_opt_pi_flags_reserved = (prefix->AdvOnLinkFlag) ? ND_OPT_PI_FLAG_ONLINK : 0;
			pinfo->nd_opt_pi_flags_reserved |= (prefix->AdvAutonomousFlag) ? ND_OPT_PI_FLAG_AUTO : 0;
			/* Mobile IPv6 ext */
			pinfo->nd_opt_pi_flags_reserved |= (prefix->AdvRouterAddr) ? ND_OPT_PI_FLAG_RADDR : 0;

			if (iface->cease_adv && prefix->DeprecatePrefixFlag) {
				/* RFC4862, 5.5.3, step e) */
				if (prefix->curr_validlft < MIN_AdvValidLifetime) {
					if (prefix->DecrementLifetimesFlag) {
						decrement_lifetime(secs_since_last_ra,
						&prefix->curr_validlft);
					}
					pinfo->nd_opt_pi_valid_time = htonl(prefix->curr_validlft);
				} else {
					pinfo->nd_opt_pi_valid_time = htonl(MIN_AdvValidLifetime);
				}
				pinfo->nd_opt_pi_preferred_time = 0;
			} else {
				if (prefix->DecrementLifetimesFlag) {
					decrement_lifetime(secs_since_last_ra, &prefix->curr_validlft);

					decrement_lifetime(secs_since_last_ra, &prefix->curr_preferredlft);
					if (prefix->curr_preferredlft == 0)
						cease_adv_pfx_msg(iface->Name, &prefix->Prefix, prefix->PrefixLen);
				}
				pinfo->nd_opt_pi_valid_time = htonl(prefix->curr_validlft);
				pinfo->nd_opt_pi_preferred_time = htonl(prefix->curr_preferredlft);

			}
			pinfo->nd_opt_pi_reserved2 = 0;

			memcpy(&pinfo->nd_opt_pi_prefix, &prefix->Prefix, sizeof(struct in6_addr));
			print_addr(&prefix->Prefix, addr_str);
			dlog(LOG_DEBUG, 5, "adding prefix %s to advert for %s with %u seconds(s) valid lifetime and %u seconds(s) preferred time",
				addr_str, iface->Name, ntohl(pinfo->nd_opt_pi_valid_time), ntohl(pinfo->nd_opt_pi_preferred_time));
		}

		prefix = prefix->next;
	}

	route = iface->AdvRouteList;

	/*
	 *      add route options
	 */

	while (route) {
		struct nd_opt_route_info_local *rinfo;

		rinfo = (struct nd_opt_route_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(*rinfo));

		rinfo->nd_opt_ri_type = ND_OPT_ROUTE_INFORMATION;
		/* XXX: the prefixes are allowed to be sent in smaller chunks as well */
		rinfo->nd_opt_ri_len = 3;
		rinfo->nd_opt_ri_prefix_len = route->PrefixLen;

		rinfo->nd_opt_ri_flags_reserved = (route->AdvRoutePreference << ND_OPT_RI_PRF_SHIFT) & ND_OPT_RI_PRF_MASK;
		if (iface->cease_adv && route->RemoveRouteFlag) {
			rinfo->nd_opt_ri_lifetime = 0;
		} else {
			rinfo->nd_opt_ri_lifetime = htonl(route->AdvRouteLifetime);
		}

		memcpy(&rinfo->nd_opt_ri_prefix, &route->Prefix, sizeof(struct in6_addr));

		route = route->next;
	}

	rdnss = iface->AdvRDNSSList;

	/*
	 *      add rdnss options
	 */

	while (rdnss) {
		struct nd_opt_rdnss_info_local *rdnssinfo;

		rdnssinfo = (struct nd_opt_rdnss_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(*rdnssinfo) - (3 - rdnss->AdvRDNSSNumber) * sizeof(struct in6_addr));

		rdnssinfo->nd_opt_rdnssi_type = ND_OPT_RDNSS_INFORMATION;
		rdnssinfo->nd_opt_rdnssi_len = 1 + 2 * rdnss->AdvRDNSSNumber;
		rdnssinfo->nd_opt_rdnssi_pref_flag_reserved = 0;

		if (iface->cease_adv && rdnss->FlushRDNSSFlag) {
			rdnssinfo->nd_opt_rdnssi_lifetime = 0;
		} else {
			rdnssinfo->nd_opt_rdnssi_lifetime = htonl(rdnss->AdvRDNSSLifetime);
		}

		memcpy(&rdnssinfo->nd_opt_rdnssi_addr1, &rdnss->AdvRDNSSAddr1, sizeof(struct in6_addr));
		memcpy(&rdnssinfo->nd_opt_rdnssi_addr2, &rdnss->AdvRDNSSAddr2, sizeof(struct in6_addr));
		memcpy(&rdnssinfo->nd_opt_rdnssi_addr3, &rdnss->AdvRDNSSAddr3, sizeof(struct in6_addr));

		rdnss = rdnss->next;
	}

	dnssl = iface->AdvDNSSLList;

	/*
	 *      add dnssl options
	 */

	while (dnssl) {
		struct nd_opt_dnssl_info_local *dnsslinfo;
		int const start_len = len;
		int i;

		dnsslinfo = (struct nd_opt_dnssl_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(dnsslinfo->nd_opt_dnssli_type) +
				sizeof(dnsslinfo->nd_opt_dnssli_len) + sizeof(dnsslinfo->nd_opt_dnssli_reserved) + sizeof(dnsslinfo->nd_opt_dnssli_lifetime)
		    );

		dnsslinfo->nd_opt_dnssli_type = ND_OPT_DNSSL_INFORMATION;
		dnsslinfo->nd_opt_dnssli_reserved = 0;

		if (iface->cease_adv && dnssl->FlushDNSSLFlag) {
			dnsslinfo->nd_opt_dnssli_lifetime = 0;
		} else {
			dnsslinfo->nd_opt_dnssli_lifetime = htonl(dnssl->AdvDNSSLLifetime);
		}

		for (i = 0; i < dnssl->AdvDNSSLNumber; i++) {
			char *label;
			int label_len;

			label = dnssl->AdvDNSSLSuffixes[i];

			while (label[0] != '\0') {
				if (strchr(label, '.') == NULL)
					label_len = strlen(label);
				else
					label_len = strchr(label, '.') - label;

				buff_dest = len;
				send_ra_inc_len(&len, 1);
				buff[buff_dest] = label_len;

				buff_dest = len;
				send_ra_inc_len(&len, label_len);
				memcpy(buff + buff_dest, label, label_len);

				label += label_len;

				if (label[0] == '.')
					label++;
				if (label[0] == '\0') {
					buff_dest = len;
					send_ra_inc_len(&len, 1);
					buff[buff_dest] = 0;
				}
			}
		}

		dnsslinfo->nd_opt_dnssli_len = (len - start_len) / 8;

		if ((len - start_len) % 8 != 0) {
			send_ra_inc_len(&len, 8 - (len - start_len) % 8);
			++dnsslinfo->nd_opt_dnssli_len;
		}

		dnssl = dnssl->next;
	}

	/*
	 *      add MTU option
	 */

	if (iface->AdvLinkMTU != 0) {
		struct nd_opt_mtu *mtu;

		mtu = (struct nd_opt_mtu *)(buff + len);

		send_ra_inc_len(&len, sizeof(*mtu));

		mtu->nd_opt_mtu_type = ND_OPT_MTU;
		mtu->nd_opt_mtu_len = 1;
		mtu->nd_opt_mtu_reserved = 0;
		mtu->nd_opt_mtu_mtu = htonl(iface->AdvLinkMTU);
	}

	/*
	 * add Source Link-layer Address option
	 */

	if (iface->AdvSourceLLAddress && iface->if_hwaddr_len > 0) {
		/*
		4.6.1.  Source/Target Link-layer Address

		      0                   1                   2                   3
		      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
		     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		     |     Type      |    Length     |    Link-Layer Address ...
		     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

		   Fields:

		      Type
				     1 for Source Link-layer Address
				     2 for Target Link-layer Address

		      Length         The length of the option (including the type and
				     length fields) in units of 8 octets.  For example,
				     the length for IEEE 802 addresses is 1 [IPv6-
				     ETHER].

		      Link-Layer Address
				     The variable length link-layer address.

				     The content and format of this field (including
				     byte and bit ordering) is expected to be specified
				     in specific documents that describe how IPv6
				     operates over different link layers.  For instance,
				     [IPv6-ETHER].

		*/
		/* +2 for the ND_OPT_SOURCE_LINKADDR and the length (each occupy one byte) */
		size_t const sllao_bytes = (iface->if_hwaddr_len / 8) + 2;
		size_t const sllao_len = (sllao_bytes + 7) / 8;
		uint8_t *sllao = (uint8_t *) (buff + len);

		send_ra_inc_len(&len, sllao_len * 8);

		*sllao++ = ND_OPT_SOURCE_LINKADDR;
		*sllao++ = (uint8_t) sllao_len;

		/* if_hwaddr_len is in bits, so divide by 8 to get the byte count. */
		memcpy(sllao, iface->if_hwaddr, iface->if_hwaddr_len / 8);
	}

	/*
	 * Mobile IPv6 ext: Advertisement Interval Option to support
	 * movement detection of mobile nodes
	 */

	if (iface->AdvIntervalOpt) {
		struct AdvInterval a_ival;
		uint32_t ival;
		if (iface->MaxRtrAdvInterval < Cautious_MaxRtrAdvInterval) {
			ival = ((iface->MaxRtrAdvInterval + Cautious_MaxRtrAdvInterval_Leeway) * 1000);

		} else {
			ival = (iface->MaxRtrAdvInterval * 1000);
		}
		a_ival.type = ND_OPT_RTR_ADV_INTERVAL;
		a_ival.length = 1;
		a_ival.reserved = 0;
		a_ival.adv_ival = htonl(ival);

		buff_dest = len;
		send_ra_inc_len(&len, sizeof(a_ival));
		memcpy(buff + buff_dest, &a_ival, sizeof(a_ival));
	}

	/*
	 * Mobile IPv6 ext: Home Agent Information Option to support
	 * Dynamic Home Agent Address Discovery
	 */

	if (iface->AdvHomeAgentInfo && (iface->AdvMobRtrSupportFlag || iface->HomeAgentPreference != 0 || iface->HomeAgentLifetime != iface->AdvDefaultLifetime)) {
		struct HomeAgentInfo ha_info;
		ha_info.type = ND_OPT_HOME_AGENT_INFO;
		ha_info.length = 1;
		ha_info.flags_reserved = (iface->AdvMobRtrSupportFlag) ? ND_OPT_HAI_FLAG_SUPPORT_MR : 0;
		ha_info.preference = htons(iface->HomeAgentPreference);
		ha_info.lifetime = htons(iface->HomeAgentLifetime);

		buff_dest = len;
		send_ra_inc_len(&len, sizeof(ha_info));
		memcpy(buff + buff_dest, &ha_info, sizeof(ha_info));
	}

	lowpanco = iface->AdvLowpanCoList;

	/*
	 * Add 6co option
	 */

	if (lowpanco) {
		struct nd_opt_6co *co;
		co = (struct nd_opt_6co *)(buff + len);

		send_ra_inc_len(&len, sizeof(*co));

		co->nd_opt_6co_type = ND_OPT_6CO;
		co->nd_opt_6co_len = 3;
		co->nd_opt_6co_context_len = lowpanco->ContextLength;
		co->nd_opt_6co_c = lowpanco->ContextCompressionFlag;
		co->nd_opt_6co_cid = lowpanco->AdvContextID;
		co->nd_opt_6co_valid_lifetime = lowpanco->AdvLifeTime;
		co->nd_opt_6co_con_prefix = lowpanco->AdvContextPrefix;
	}

	abroo = iface->AdvAbroList;

	/*
	 * Add ABRO option
	 */

	if (abroo) {
		struct nd_opt_abro *abro;
		abro = (struct nd_opt_abro *)(buff + len);

		send_ra_inc_len(&len, sizeof(*abro));

		abro->nd_opt_abro_type = ND_OPT_ABRO;
		abro->nd_opt_abro_len = 3;
		abro->nd_opt_abro_ver_low = abroo->Version[1];
		abro->nd_opt_abro_ver_high = abroo->Version[0];
		abro->nd_opt_abro_valid_lifetime = abroo->ValidLifeTime;
		abro->nd_opt_abro_6lbr_address = abroo->LBRaddress;
	}

	err = really_send(dest, iface->if_index, iface->if_addr, buff, len);

	if (err < 0) {
		if (!iface->IgnoreIfMissing || !(errno == EINVAL || errno == ENODEV))
			flog(LOG_WARNING, "sendmsg: %s", strerror(errno));
		else
			dlog(LOG_DEBUG, 3, "sendmsg: %s", strerror(errno));
	}

	return 0;
}
Example #13
0
/* open device level access to cd rom drive */
static int sys_cddev_open (struct dev_info_ioctl *ciw, int unitnum)
{

	ciw->cdda_volume[0] = 0x7fff;
	ciw->cdda_volume[1] = 0x7fff;
	/* buffer must be page aligned for device access */
	ciw->tempbuffer = (uae_u8*)VirtualAlloc (NULL, IOCTL_DATA_BUFFER, MEM_COMMIT, PAGE_READWRITE);
	if (!ciw->tempbuffer) {
		write_log (_T("IOCTL: failed to allocate buffer"));
		return 1;
	}

	memset (ciw->di.vendorid, 0, sizeof ciw->di.vendorid);
	memset (ciw->di.productid, 0, sizeof ciw->di.productid);
	memset (ciw->di.revision, 0, sizeof ciw->di.revision);
	_tcscpy (ciw->di.vendorid, _T("UAE"));
	_stprintf (ciw->di.productid, _T("SCSI CD%d IMG"), unitnum);
	_tcscpy (ciw->di.revision, _T("0.2"));

#if 0
	uae_u8 inquiry[256];
	int datalen;
	memset (inquiry, 0, sizeof inquiry);
	if (spti_inquiry (ciw, unitnum, inquiry, &datalen)) {
		// check also that device type is non-zero and it is removable
		if (datalen >= 36 && (inquiry[0] & 31) && (inquiry[1] & 0x80) && inquiry[8]) {
			char tmp[20];
			TCHAR *s;
			memcpy (tmp, inquiry + 8, 8);
			tmp[8] = 0;
			s = au (tmp);
			trim (s);
			_tcscpy (ciw->di.vendorid, s);
			xfree (s);
			memcpy (tmp, inquiry + 16, 16);
			tmp[16] = 0;
			s = au (tmp);
			trim (s);
			_tcscpy (ciw->di.productid, s);
			xfree (s);
			memcpy (tmp, inquiry + 32, 4);
			tmp[4] = 0;
			s = au (tmp);
			trim (s);
			_tcscpy (ciw->di.revision, s);
			xfree (s);
		}
		close_createfile (ciw);
	}
#endif

	if (!open_createfile (ciw, 0)) {
		write_log (_T("IOCTL: failed to open '%s', err=%d\n"), ciw->devname, GetLastError ());
		goto error;
	}

	STORAGE_PROPERTY_QUERY query;
	UCHAR outBuf[20000];
	ULONG returnedLength;
	memset (&query, 0, sizeof query);
	query.PropertyId = StorageDeviceProperty;
	query.QueryType = PropertyStandardQuery;
	if (DeviceIoControl(
		ciw->h,
		IOCTL_STORAGE_QUERY_PROPERTY,
		&query,
		sizeof (STORAGE_PROPERTY_QUERY),
		&outBuf,
		sizeof (outBuf),
		&returnedLength,
		NULL
	)) {
		PSTORAGE_DEVICE_DESCRIPTOR devDesc;
		devDesc = (PSTORAGE_DEVICE_DESCRIPTOR) outBuf;
		int size = devDesc->Version;
		PUCHAR p = (PUCHAR) outBuf;
		for (;;) {
			if (offsetof(STORAGE_DEVICE_DESCRIPTOR, CommandQueueing) > size)
				break;
			if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, VendorIdOffset) && devDesc->VendorIdOffset && p[devDesc->VendorIdOffset]) {
				ciw->di.vendorid[0] = 0;
				ciw->di.productid[0] = 0;
				ciw->di.revision[0] = 0;
				int j = 0;
				for (int i = devDesc->VendorIdOffset; p[i] != (UCHAR) NULL && i < returnedLength && j < sizeof (ciw->di.vendorid) / sizeof (TCHAR) - 1; i++)
					ciw->di.vendorid[j++] = p[i];
			}
			if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, ProductIdOffset) && devDesc->ProductIdOffset && p[devDesc->ProductIdOffset]) {
				int j = 0;
				for (int i = devDesc->ProductIdOffset; p[i] != (UCHAR) NULL && i < returnedLength && j < sizeof (ciw->di.productid) / sizeof (TCHAR) - 1; i++)
					ciw->di.productid[j++] = p[i];
			}
			if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, ProductRevisionOffset) && devDesc->ProductRevisionOffset && p[devDesc->ProductRevisionOffset]) {
				int j = 0;
				for (int i = devDesc->ProductRevisionOffset; p[i] != (UCHAR) NULL && i < returnedLength && j < sizeof (ciw->di.revision) / sizeof (TCHAR) - 1; i++)
					 ciw->di.revision[j++] = p[i];
			}
			trim (ciw->di.vendorid);
			trim (ciw->di.productid);
			trim (ciw->di.revision);
			break;
		}
	}

	write_log (_T("IOCTL: device '%s' (%s/%s/%s) opened succesfully (unit=%d,media=%d)\n"),
		ciw->devname, ciw->di.vendorid, ciw->di.productid, ciw->di.revision,
		unitnum, ciw->di.media_inserted);
	if (!_tcsicmp (ciw->di.vendorid, _T("iomega")) && !_tcsicmp (ciw->di.productid, _T("rrd"))) {
		write_log (_T("Device blacklisted\n"));
		goto error2;
	}
	uae_sem_init (&ciw->sub_sem, 0, 1);
	uae_sem_init (&ciw->sub_sem2, 0, 1);
	//ciw->usesptiread = true;
	ioctl_command_stop (unitnum);
	update_device_info (unitnum);
	ciw->open = true;
	return 0;
error:
	win32_error (ciw, unitnum, _T("CreateFile"));
error2:
	VirtualFree (ciw->tempbuffer, 0, MEM_RELEASE);
	ciw->tempbuffer = NULL;
	CloseHandle (ciw->h);
	ciw->h = NULL;
	return -1;
}