Пример #1
0
int board_cut_off_battery(void)
{
	int rv;

	/* Ship mode command must be sent twice to take effect */
	rv = sb_write(SB_MANUFACTURER_ACCESS, SB_SHUTDOWN_DATA);
	if (rv != EC_SUCCESS)
		return EC_RES_ERROR;

	rv = sb_write(SB_MANUFACTURER_ACCESS, SB_SHUTDOWN_DATA);
	return rv ? EC_RES_ERROR : EC_RES_SUCCESS;
}
Пример #2
0
static int cutoff(void)
{
	int rv;

	/* Ship mode command must be sent twice to take effect */
	rv = sb_write(SB_MANUFACTURER_ACCESS, SB_SHUTDOWN_DATA);

	if (rv != EC_SUCCESS)
		return rv;

	return sb_write(SB_MANUFACTURER_ACCESS, SB_SHUTDOWN_DATA);
}
Пример #3
0
enum battery_disconnect_state battery_get_disconnect_state(void)
{
	uint8_t data[6];
	int rv;

	/*
	 * Take note if we find that the battery isn't in disconnect state,
	 * and always return NOT_DISCONNECTED without probing the battery.
	 * This assumes the battery will not go to disconnect state during
	 * runtime.
	 */
	static int not_disconnected;

	if (not_disconnected)
		return BATTERY_NOT_DISCONNECTED;

	if (extpower_is_present()) {
		/* Check if battery charging + discharging is disabled. */
		rv = sb_write(SB_MANUFACTURER_ACCESS, PARAM_OPERATION_STATUS);
		if (rv)
			return BATTERY_DISCONNECT_ERROR;

		rv = sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
				    SB_ALT_MANUFACTURER_ACCESS, data, 6);

		if (rv || (~data[3] & (BATTERY_DISCHARGING_DISABLED |
				       BATTERY_CHARGING_DISABLED))) {
			not_disconnected = 1;
			return BATTERY_NOT_DISCONNECTED;
		}

		/*
		 * Battery is neither charging nor discharging. Verify that
		 * we didn't enter this state due to a safety fault.
		 */
		rv = sb_write(SB_MANUFACTURER_ACCESS, PARAM_SAFETY_STATUS);
		if (rv)
			return BATTERY_DISCONNECT_ERROR;

		rv = sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
				    SB_ALT_MANUFACTURER_ACCESS, data, 6);

		if (rv || data[2] || data[3] || data[4] || data[5])
			return BATTERY_DISCONNECT_ERROR;

		/* No safety fault, battery is disconnected */
		return BATTERY_DISCONNECTED;
	}
	not_disconnected = 1;
	return BATTERY_NOT_DISCONNECTED;
}
Пример #4
0
static void
request_handler (aeEventLoop * el, int fd, void *data, int mask)
{
  workerState *ws = (workerState *) data;
  simpleBuf *sb = &ws->out;
  int tw;

  if (ws->reconn_after > 0LL)
    {
      ws->reconn_after = 0LL;
    }

  tw = sb_write (sb, fd);
  if (tw < 0)
    {
      fprintf (stderr, "[smr-client] failed to sb_write:%d\n", tw);
      free_connection (ws, 1);
      return;
    }

  if (sb->ep - sb->cp == 0)
    {
      sb->cp = sb->buf;		//reset sb
      aeDeleteFileEvent (el, fd, AE_WRITABLE);
      ws->wprepared = 0;
    }
  return;
}
static int test_low_battery(void)
{
	test_setup(1);

	ccprintf("[CHARGING TEST] Low battery with AC\n");

	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
	wait_charging_state();
	mock_chipset_state = CHIPSET_STATE_SOFT_OFF;
	hook_notify(HOOK_CHIPSET_SHUTDOWN);
	TEST_ASSERT(!is_hibernated);

	ccprintf("[CHARGING TEST] Low battery shutdown S0->S5\n");
	mock_chipset_state = CHIPSET_STATE_ON;
	hook_notify(HOOK_CHIPSET_PRE_INIT);
	hook_notify(HOOK_CHIPSET_STARTUP);
	gpio_set_level(GPIO_AC_PRESENT, 0);
	is_hibernated = 0;
	sb_write(SB_CURRENT, -1000);
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
	wait_charging_state();
	mock_chipset_state = CHIPSET_STATE_SOFT_OFF;
	hook_notify(HOOK_CHIPSET_SHUTDOWN);
	wait_charging_state();
	TEST_ASSERT(is_hibernated);

	ccprintf("[CHARGING TEST] Low battery shutdown S5\n");
	is_hibernated = 0;
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 10);
	wait_charging_state();
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
	wait_charging_state();
	TEST_ASSERT(is_hibernated);

	ccprintf("[CHARGING TEST] Low battery AP shutdown\n");
	is_shutdown = 0;
	mock_chipset_state = CHIPSET_STATE_ON;
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 10);
	gpio_set_level(GPIO_AC_PRESENT, 1);
	sb_write(SB_CURRENT, 1000);
	wait_charging_state();
	gpio_set_level(GPIO_AC_PRESENT, 0);
	sb_write(SB_CURRENT, -1000);
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
	wait_charging_state();
	usleep(32 * SECOND);
	wait_charging_state();
	TEST_ASSERT(is_shutdown);

	return EC_SUCCESS;
}
Пример #6
0
static int ctl_msg_recv(void)
{
	int len;
	uint8_t buf[1024];

	while( (len = recv(ctrl_fd, buf, sizeof(buf), 0)) > 0){
		sb_write(sb_in, buf, len);
	}

	return 0;
}
Пример #7
0
static int test_high_temp_battery(void)
{
	test_setup(1);

	ccprintf("[CHARGING TEST] High battery temperature shutdown\n");
	ev_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN);
	sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(90));
	wait_charging_state();
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_SHUTDOWN));
	TEST_ASSERT(!is_shutdown);
	sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
	TEST_ASSERT(is_shutdown);

	ccprintf("[CHARGING TEST] High battery temp S0->S5 hibernate\n");
	mock_chipset_state = CHIPSET_STATE_SOFT_OFF;
	wait_charging_state();
	TEST_ASSERT(is_hibernated);

	return EC_SUCCESS;
}
static int test_low_battery_hostevents(void)
{
	int state;

	test_setup(0);

	ccprintf("[CHARGING TEST] Low battery host events\n");

	/* You know you make me wanna */
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_LOW + 1);
	ev_clear(EC_HOST_EVENT_BATTERY_LOW);
	ev_clear(EC_HOST_EVENT_BATTERY_CRITICAL);
	ev_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_LOW));
	TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_CRITICAL));
	TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN));

	/* (Shout) a little bit louder now */
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_LOW - 1);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW));
	TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_CRITICAL));
	TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN));
	TEST_ASSERT(!is_shutdown);

	/* (Shout) a little bit louder now */
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_CRITICAL + 1);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW));
	TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_CRITICAL));
	TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN));
	TEST_ASSERT(!is_shutdown);

	/* (Shout) a little bit louder now */
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_CRITICAL - 1);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW));
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_CRITICAL));
	TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN));
	TEST_ASSERT(!is_shutdown);

	/* (Shout) a little bit louder now */
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_SHUTDOWN + 1);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW));
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_CRITICAL));
	TEST_ASSERT(ev_is_clear(EC_HOST_EVENT_BATTERY_SHUTDOWN));
	TEST_ASSERT(!is_shutdown);

	/* (Shout) a little bit louder now */
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_SHUTDOWN - 1);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW));
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_CRITICAL));
	/* hey-hey-HEY-hey. Doesn't immediately shut down */
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_SHUTDOWN));
	TEST_ASSERT(!is_shutdown);
	/* after a while, the AP should shut down */
	sleep(LOW_BATTERY_SHUTDOWN_TIMEOUT);
	TEST_ASSERT(is_shutdown);

	return EC_SUCCESS;
}
static int test_charge_state(void)
{
	enum charge_state state;
	uint32_t flags;

	/* On AC */
	test_setup(1);

	ccprintf("[CHARGING TEST] AC on\n");

	/* Detach battery, charging error */
	ccprintf("[CHARGING TEST] Detach battery\n");
	TEST_ASSERT(test_detach_i2c(I2C_PORT_BATTERY, BATTERY_ADDR) ==
		    EC_SUCCESS);
	msleep(BATTERY_DETACH_DELAY);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_ERROR);

	/* Attach battery again, charging */
	ccprintf("[CHARGING TEST] Attach battery\n");
	test_attach_i2c(I2C_PORT_BATTERY, BATTERY_ADDR);
	/* And changing full capacity should trigger a host event */
	ev_clear(EC_HOST_EVENT_BATTERY);
	sb_write(SB_FULL_CHARGE_CAPACITY, 0xeff0);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_CHARGE);
	TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY));

	/* Unplug AC, discharging at 1000mAh */
	ccprintf("[CHARGING TEST] AC off\n");
	gpio_set_level(GPIO_AC_PRESENT, 0);
	sb_write(SB_CURRENT, -1000);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	flags = charge_get_flags();
	TEST_ASSERT(!(flags & CHARGE_FLAG_EXTERNAL_POWER));
	TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE));

	/* Discharging waaaay overtemp is ignored */
	ccprintf("[CHARGING TEST] AC off, batt temp = 0xffff\n");
	gpio_set_level(GPIO_AC_PRESENT, 0);
	sb_write(SB_CURRENT, -1000);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	sb_write(SB_TEMPERATURE, 0xffff);
	state = wait_charging_state();
	TEST_ASSERT(!is_shutdown);
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(40));

	/* Discharging overtemp */
	ccprintf("[CHARGING TEST] AC off, batt temp = 90 C\n");
	gpio_set_level(GPIO_AC_PRESENT, 0);
	sb_write(SB_CURRENT, -1000);

	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(90));
	state = wait_charging_state();
	TEST_ASSERT(is_shutdown);
	TEST_ASSERT(state == PWR_STATE_DISCHARGE);
	sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(40));

	/* Force idle */
	ccprintf("[CHARGING TEST] AC on, force idle\n");
	gpio_set_level(GPIO_AC_PRESENT, 1);
	sb_write(SB_CURRENT, 1000);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_CHARGE);
	flags = charge_get_flags();
	TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
	TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE));
	charge_control(CHARGE_CONTROL_IDLE);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_IDLE);
	flags = charge_get_flags();
	TEST_ASSERT(flags & CHARGE_FLAG_EXTERNAL_POWER);
	TEST_ASSERT(flags & CHARGE_FLAG_FORCE_IDLE);
	charge_control(CHARGE_CONTROL_NORMAL);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_CHARGE);

	/* Force discharge */
	ccprintf("[CHARGING TEST] AC on, force discharge\n");
	gpio_set_level(GPIO_AC_PRESENT, 1);
	sb_write(SB_CURRENT, 1000);
	charge_control(CHARGE_CONTROL_DISCHARGE);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_IDLE);
	TEST_ASSERT(is_force_discharge);
	charge_control(CHARGE_CONTROL_NORMAL);
	state = wait_charging_state();
	TEST_ASSERT(state == PWR_STATE_CHARGE);
	TEST_ASSERT(!is_force_discharge);

	return EC_SUCCESS;
}
Пример #10
0
void sb_vfdprintf(int fd, const char *format, va_list args)
{
    const char *fmt = format;
    const char *format_end = format + strlen(format);
    const char *conv = fmt;

    while (fmt < format_end) {
        conv = memchr(fmt, '%', format_end - fmt);

        if (conv != fmt) {
            size_t out_bytes = (conv ? conv : format_end) - fmt;
            sb_write(fd, fmt, out_bytes);
            if (!conv)
                return;
        }

        char buf[50];
        size_t idx;
        unsigned int u, x;
        char hex_base;
        size_t padding = 0;

        unsigned int modifiers = 0;
eat_more:
        switch (conv[1]) {
        default:
            sb_fdprintf(fd, "{invalid conversion specifier in string: %s}", format);
            break;

        case '%':
            if (modifiers) {
inv_modifier:
                sb_fdprintf(fd, "{invalid modifier in string: %s}", format);
            }
            sb_write(fd, conv, 1);
            break;
        case 'z':
            ++conv;
            if (modifiers & MOD_SIZE_T)
                goto inv_modifier;
            modifiers |= MOD_SIZE_T;
            goto eat_more;
        case '*':
            ++conv;
            if (modifiers & MOD_STAR)
                goto inv_modifier;
            modifiers |= MOD_STAR;
            padding = va_arg(args, int);
            goto eat_more;

        case 'c': {
            char c = va_arg(args, int);
            sb_write(fd, &c, 1);
            break;
        }
        case 's': {
            char *s = va_arg(args, char *);
            if (!s)
                s = "(null)";
            size_t len = strlen(s);
            while (len < padding--)
                sb_write(fd, " ", 1);
            sb_write(fd, s, len);
            break;
        }

        case 'd':
        case 'i': {
            long i;
            if (modifiers & MOD_SIZE_T)
                i = va_arg(args, ssize_t);
            else
                i = va_arg(args, int);
            u = i;
            if (i < 0) {
                sb_write(fd, "-", 1);
                u = i * -1;
            }
out_uint:
            idx = 0;
            do {
                buf[idx++] = '0' + (u % 10);
            } while (u /= 10);
            while (idx--)
                sb_write(fd, buf+idx, 1);
            break;
        }
        case 'u': {
            u = va_arg(args, unsigned int);
            goto out_uint;
            break;
        }

        case 'X': {
            hex_base = 'A';
            goto out_hex;
        }
        case 'x': {
            hex_base = 'a';
out_hex:
            if (modifiers & MOD_SIZE_T)
                x = va_arg(args, size_t);
            else
                x = va_arg(args, unsigned int);
out_ptr:
            idx = 0;
            do {
                u = x % 16;
                buf[idx++] = (u < 10 ? '0' + u : hex_base + u - 10);
            } while (x /= 16);
            while (idx < padding)
                buf[idx++] = '0';
            buf[idx++] = 'x';
            buf[idx++] = '0';
            while (idx--)
                sb_write(fd, buf+idx, 1);
            break;
        }
        case 'p': {
            void *p = va_arg(args, void *);
            hex_base = 'a';
            padding = sizeof(p) * 2;
            x = (unsigned long)p;
            goto out_ptr;
        }
        }

        fmt = conv + 2;
    }
}
Пример #11
0
static int test_low_battery(void)
{
	test_setup(1);

	ccprintf("[CHARGING TEST] Low battery with AC and positive current\n");
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
	sb_write(SB_CURRENT, 1000);
	wait_charging_state();
	mock_chipset_state = CHIPSET_STATE_SOFT_OFF;
	hook_notify(HOOK_CHIPSET_SHUTDOWN);
	TEST_ASSERT(!is_hibernated);

	ccprintf("[CHARGING TEST] Low battery with AC and negative current\n");
	sb_write(SB_CURRENT, -1000);
	wait_charging_state();
	sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
	TEST_ASSERT(is_hibernated);

	ccprintf("[CHARGING TEST] Low battery shutdown S0->S5\n");
	mock_chipset_state = CHIPSET_STATE_ON;
	hook_notify(HOOK_CHIPSET_PRE_INIT);
	hook_notify(HOOK_CHIPSET_STARTUP);
	gpio_set_level(GPIO_AC_PRESENT, 0);
	is_hibernated = 0;
	sb_write(SB_CURRENT, -1000);
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
	wait_charging_state();
	mock_chipset_state = CHIPSET_STATE_SOFT_OFF;
	hook_notify(HOOK_CHIPSET_SHUTDOWN);
	wait_charging_state();
	/* after a while, the EC should hibernate */
	sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
	TEST_ASSERT(is_hibernated);

	ccprintf("[CHARGING TEST] Low battery shutdown S5\n");
	is_hibernated = 0;
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 10);
	wait_charging_state();
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
	wait_charging_state();
	/* after a while, the EC should hibernate */
	sleep(CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT);
	TEST_ASSERT(is_hibernated);

	ccprintf("[CHARGING TEST] Low battery AP shutdown\n");
	is_shutdown = 0;
	mock_chipset_state = CHIPSET_STATE_ON;
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 10);
	gpio_set_level(GPIO_AC_PRESENT, 1);
	sb_write(SB_CURRENT, 1000);
	wait_charging_state();
	gpio_set_level(GPIO_AC_PRESENT, 0);
	sb_write(SB_CURRENT, -1000);
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
	wait_charging_state();
	usleep(32 * SECOND);
	wait_charging_state();
	TEST_ASSERT(is_shutdown);

	return EC_SUCCESS;
}
Пример #12
0
int board_cut_off_battery(void)
{
	return sb_write(SB_SHIP_MODE_ADDR, SB_SHIP_MODE_DATA);
}
Пример #13
0
/* Returns 0 on success, non-zero on failure */
static int save_table(
    lua_State * L,
    luaamf_SaveBuffer * sb,
    int index
  )
{
  luaamf_SaveBuffer numeric;
  luaamf_SaveBuffer associative;
  int result = LUAAMF_ESUCCESS;
  int numeric_index = 1;
  int key_value_pairs_number = 0;

  {
    void * alloc_ud = NULL;
    lua_Alloc alloc_fn = lua_getallocf(L, &alloc_ud);
    sb_init(&numeric, alloc_fn, alloc_ud);
    sb_init(&associative, alloc_fn, alloc_ud);
  }

  lua_pushnil(L);
  while (result == LUAAMF_ESUCCESS && lua_next(L, index) != 0)
  {
    int value_pos = lua_gettop(L);  /* We need absolute values */
    int key_pos = value_pos - 1;

    if(lua_type(L, key_pos) == LUA_TNUMBER && lua_tonumber(L, key_pos) == (float)numeric_index)
    {
      /* Save enumerated value. */
      result = save_value(&numeric, L, value_pos, 1);
      numeric_index++;
    }
    else
    {
      /* Save associative key. */
      result = save_value(&associative, L, key_pos, 0);

      /* Save associative value. */
      if (result == LUAAMF_ESUCCESS)
      {
        result = save_value(&associative, L, value_pos, 1);
        key_value_pairs_number++;
      }
    }

    if (result == LUAAMF_ESUCCESS)
    {
      /* Remove value from stack, leave key for the next iteration. */
      lua_pop(L, 1);
    }
    else
    {
      return result;
    }
  }

  /* write serilization here */
  sb_writechar(sb, LUAAMF_ARRAY);
  encode_int(sb, 2 * key_value_pairs_number + 1);
  sb_write(sb, sb_buffer(&associative, &(associative.buf_size)), associative.buf_size);
  sb_writechar(sb, 0x001);
  sb_write(sb, sb_buffer(&numeric, &(numeric.buf_size)), numeric.buf_size);
  result = LUAAMF_ESUCCESS;

  sb_destroy(&numeric);
  sb_destroy(&associative);
  return result;
}
Пример #14
0
static void cutoff(void)
{
	/* Claim i2c and send cutoff command to battery. */
	sb_write(SB_MANUFACTURER_ACCESS, PARAM_CUT_OFF);
}
Пример #15
0
void sb_vfdprintf(int fd, const char *format, va_list args)
{
	const char *fmt = format;
	const char *format_end = format + strlen(format);
	const char *conv = fmt;

	while (fmt < format_end) {
		conv = memchr(fmt, '%', format_end - fmt);

		if (conv != fmt) {
			size_t out_bytes = (conv ? conv : format_end) - fmt;
			sb_write(fd, fmt, out_bytes);
			if (!conv)
				return;
		}

		char buf[50];
		size_t idx;
		unsigned long long int u, x;
		char hex_base;
		size_t padding = 0;

		unsigned int modifiers = 0;
 eat_more:
		switch (conv[1]) {
			default:
				sb_fdprintf(fd, "{invalid conversion specifier in string: %s}", format);
				break;

			case '%':
				if (modifiers) {
 inv_modifier:
					sb_fdprintf(fd, "{invalid modifier in string: %s}", format);
				}
				sb_write(fd, conv, 1);
				break;
			case 'l':
				++conv;
				if (modifiers & MOD_LONG_T) {
					if (modifiers & MOD_LONG_LONG_T)
						goto inv_modifier;
					modifiers = (modifiers & ~MOD_LONG_T) | MOD_LONG_LONG_T;
				} else
					modifiers |= MOD_LONG_T;
				goto eat_more;
			case 'z':
				++conv;
				if (modifiers & MOD_SIZE_T)
					goto inv_modifier;
				modifiers |= MOD_SIZE_T;
				goto eat_more;
			case '*':
				++conv;
				if (modifiers & MOD_STAR)
					goto inv_modifier;
				modifiers |= MOD_STAR;
				padding = va_arg(args, int);
				goto eat_more;
			case '#':
				/* ignore */
				++conv;
				goto eat_more;

			case 'c': {
				char c = va_arg(args, int);
				sb_write(fd, &c, 1);
				break;
			}
			case 's': {
				char *s = va_arg(args, char *);
				if (!s)
					s = "(null)";
				size_t len = strlen(s);
				while (len < padding--)
					sb_write(fd, " ", 1);
				sb_write(fd, s, len);
				break;
			}

			case 'd':
			case 'i': {
				long long i;
				if (modifiers & MOD_SIZE_T)
					i = va_arg(args, ssize_t);
				else if (modifiers & MOD_LONG_T)
					i = va_arg(args, long);
				else if (modifiers & MOD_LONG_LONG_T)
					i = va_arg(args, long long);
				else
					i = va_arg(args, int);
				u = i;
				if (i < 0) {
					sb_write(fd, "-", 1);
					u = i * -1;
				}
 out_uint:
				idx = 0;
				do {
					buf[idx++] = '0' + (u % 10);
				} while (u /= 10);
				while (idx--)
					sb_write(fd, buf+idx, 1);
				break;
			}
			case 'u': {
				if (modifiers & MOD_SIZE_T)
					u = va_arg(args, size_t);
				else if (modifiers & MOD_LONG_T)
					u = va_arg(args, unsigned long);
				else if (modifiers & MOD_LONG_LONG_T)
					u = va_arg(args, unsigned long long);
				else
Пример #16
0
static void set_battery_soc(int soc)
{
	sb_write(SB_RELATIVE_STATE_OF_CHARGE, soc);
	sb_write(SB_ABSOLUTE_STATE_OF_CHARGE, soc);
}