static bool alarms_timeout_subscribe_cb(LSHandle *sh, LSMessage *message, void *ctx) { bool retVal; bool fired = false; struct context *alrm_ctx = (struct context *)ctx; const char *payload = LSMessageGetPayload(message); struct json_object *object = json_tokener_parse(payload); if (is_error(object)) { POWERDLOG(LOG_CRIT,"%s: invalid json from sleep daemon",__func__); } else { fired = json_object_get_boolean(json_object_object_get(object, "fired")); } POWERDLOG(LOG_INFO,"%s: response with payload %s, count : %d", __FUNCTION__, payload, alrm_ctx->count); if(alrm_ctx->replyMessage) { if(fired) { retVal = LSMessageReply(GetLunaServiceHandle(), alrm_ctx->replyMessage, payload, NULL); if (!retVal) { POWERDLOG(LOG_WARNING, "%s could not send reply.", __FUNCTION__); } } else if(LSMessageGetConnection(alrm_ctx->replyMessage)) { retVal = LSMessageReply(LSMessageGetConnection(alrm_ctx->replyMessage), alrm_ctx->replyMessage, payload, NULL); if (!retVal) { POWERDLOG(LOG_WARNING, "%s could not send reply.", __FUNCTION__); } } alrm_ctx->count++; } else POWERDLOG(LOG_CRIT,"%s: replyMessage is NULL",__func__); if(alrm_ctx->count == 2) { if(!LSCallCancel(sh, alrm_ctx->call_token, NULL)) { POWERDLOG(LOG_WARNING, "%s could not cancel luna-service alarm call.", __FUNCTION__); } LSMessageUnref(alrm_ctx->replyMessage); free(alrm_ctx); } if (!is_error(object)) json_object_put(object); return true; }
static BatteryState StateAuthenticOrNot(void) { nyx_battery_status_t battery; battery_read(&battery); if(ChargerIsCharging() && battery.current <= 0 ) { POWERDLOG(LOG_INFO,"%d: BATTERY DISCHARGING ....",discharge_count); discharge_count++; } else discharge_count = 0; if(discharge_count == MAX_DISCHARGE_COUNT) { POWERDLOG(LOG_CRIT,"Battery discharging while on charger"); discharge_count = 0; } if(!battery.present) { return kBatteryDebounce; } if(sample_is_new(&battery)) sendBatteryStatus(); return kBatteryLast; }
void battery_set_wakeup_percentage(bool charging, bool suspend) { int battlowpercent[] = {20,13,11,9,6,5,4,3,2,1,0}; nyx_battery_status_t batt; int nextchk = 0,i = 0; if(!battDev) return; POWERDLOG(LOG_DEBUG, "In %s\n",__FUNCTION__); battery_read(&batt); sendBatteryStatus(); if(charging) { nextchk = 0; } else if(suspend) { for(i=0; battlowpercent[i]!=0; i++) { if(batt.percentage > battlowpercent[i]) { nextchk=battlowpercent[i]; break; } } } else nextchk=batt.percentage; POWERDLOG(LOG_DEBUG, "Setting percent limit to %d\n",nextchk); nyx_battery_set_wakeup_percentage(battDev, nextchk); }
bool chargerStatusQuery(LSHandle *sh, LSMessage *message, void *user_data) { nyx_charger_status_t status; if(!nyxDev) return false; nyx_error_t err = nyx_charger_query_charger_status(nyxDev,&status); if(err != NYX_ERROR_NONE) { POWERDLOG(LOG_ERR,"%s: nyx_charger_query_battery_status returned with error : %d",__func__,err); } LSError lserror; LSErrorInit(&lserror); char *payload = g_strdup_printf("{\"DockConnected\":%s,\"DockPower\":%s,\"DockSerialNo\":\"%s\"," "\"USBConnected\":%s,\"USBName\":\"%s\",\"Charging\":%s}",(status.connected & NYX_CHARGER_INDUCTIVE_CONNECTED) ? "true" : "false", (status.powered & NYX_CHARGER_INDUCTIVE_POWERED) ? "true" :"false",(strlen(status.dock_serial_number)) ? status.dock_serial_number : "NULL", (status.powered & NYX_CHARGER_USB_POWERED) ? "true" : "false",ChargerNameToString(status.connected), (status.is_charging) ? "true":"false"); POWERDLOG(LOG_DEBUG,"%s: Sending payload : %s",__func__,payload); bool retVal = LSMessageReply(sh, message, payload,NULL); if (!retVal) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } g_free(payload); return TRUE; }
void sendBatteryStatus(void) { nyx_battery_status_t status; if(!battDev) return; nyx_error_t err = nyx_battery_query_battery_status(battDev,&status); if(err != NYX_ERROR_NONE) { POWERDLOG(LOG_ERR,"%s: nyx_charger_query_battery_status returned with error : %d",__func__,err); } int percent_ui = getUiPercent(status.percentage); POWERDLOG(LOG_INFO, "(%fmAh, %d%%, %d%%_ui, %dC, %dmA, %dmV)\n", status.capacity, status.percentage, percent_ui, status.temperature, status.current, status.voltage); GString *buffer = g_string_sized_new(500); g_string_append_printf(buffer,"{\"percent\":%d,\"percent_ui\":%d," "\"temperature_C\":%d,\"current_mA\":%d,\"voltage_mV\":%d," "\"capacity_mAh\":%f}", status.percentage, percent_ui, status.temperature, status.current, status.voltage, status.capacity); char *payload = g_string_free(buffer, FALSE); POWERDLOG(LOG_DEBUG,"%s: Sending payload : %s",__func__,payload); LSError lserror; LSErrorInit(&lserror); bool retVal = LSSignalSend(GetLunaServiceHandle(), "luna://com.palm.powerd/com/palm/power/batteryStatus", payload, &lserror); if (!retVal) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } g_free(payload); return; }
bool batteryStatusQuery(LSHandle *sh, LSMessage *message, void *user_data) { nyx_battery_status_t status; if(!battDev) return false; nyx_error_t err = nyx_battery_query_battery_status(battDev,&status); if(err != NYX_ERROR_NONE) { POWERDLOG(LOG_ERR,"%s: nyx_charger_query_battery_status returned with error : %d",__func__,err); } int percent_ui = getUiPercent(status.percentage); POWERDLOG(LOG_INFO, "(%fmAh, %d%%, %d%%_ui, %dC, %dmA, %dmV)\n", status.capacity, status.percentage, percent_ui, status.temperature, status.current, status.voltage); GString *buffer = g_string_sized_new(500); g_string_append_printf(buffer,"{\"percent\":%d,\"percent_ui\":%d," "\"temperature_C\":%d,\"current_mA\":%d,\"voltage_mV\":%d," "\"capacity_mAh\":%f}", status.percentage, percent_ui, status.temperature, status.current, status.voltage, status.capacity); char *payload = g_string_free(buffer, FALSE); POWERDLOG(LOG_DEBUG,"%s: Sending payload : %s",__func__,payload); LSError lserror; LSErrorInit(&lserror); bool retVal = LSMessageReply(sh, message, payload,NULL); if (!retVal) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } g_free(payload); return TRUE; }
static int _power_timeout_init(void) { /* Set up luna service */ psh = GetPalmService(); LSError lserror; LSErrorInit(&lserror); if (!LSPalmServiceRegisterCategory(psh, "/timeout", timeout_methods /*public*/, NULL /*private*/, NULL, NULL, &lserror)) { POWERDLOG(LOG_ERR, "%s could not register category: %s", __FUNCTION__, lserror.message); LSErrorFree(&lserror); goto error; } if (!LSRegisterCategory(GetLunaServiceHandle(), "/time", time_methods, NULL, NULL, &lserror)) { goto error; } UEventListen("/com/palm/powerd/timechange/uevent", _timechange_callback); return 0; error: return -1; }
/** * @brief Log the current state. */ static void battery_state_log() { static BatteryState last_state = kBatteryLast; if (last_state != state_node.state) { POWERDLOG(LOG_INFO, "BatteryState %s", debug_battery_state[state_node.state]); last_state = state_node.state; } }
/** * @brief State "notauthentic". */ static BatteryState StateNotAuthentic(void) { if (battery_authenticate()) { return kBatteryAuthentic; } else POWERDLOG(LOG_CRIT,"Battery authentication failure"); return StateAuthenticOrNot(); }
static bool suspend_ipc_method_cb(LSHandle *sh, LSMessage *message, void *ctx) { bool retVal; LSMessage *replyMessage = (LSMessage *)ctx; POWERDLOG(LOG_INFO,"%s: response with payload %s", __FUNCTION__, LSMessageGetPayload(message)); if(replyMessage && LSMessageGetConnection(replyMessage)) { retVal = LSMessageReply(LSMessageGetConnection(replyMessage), replyMessage, LSMessageGetPayload(message), NULL); if (!retVal) { POWERDLOG(LOG_WARNING, "%s could not send reply.", __FUNCTION__); } LSMessageUnref(replyMessage); } else POWERDLOG(LOG_CRIT,"%s: replyMessage is NULL",__func__); return true; }
void getNewEvent(void) { nyx_charger_event_t new_event; nyx_error_t err = nyx_charger_query_charger_event(nyxDev,&new_event); if(err != NYX_ERROR_NONE) { POWERDLOG(LOG_ERR,"%s: nyx_charger_query_event returned with error : %d",__func__,err); } handle_charger_event(new_event); }
void notifyStateChange(nyx_device_handle_t handle, nyx_callback_status_t status, void* data) { nyx_charger_event_t new_event; nyx_error_t err = nyx_charger_query_charger_event(nyxDev,&new_event); if(err != NYX_ERROR_NONE) { POWERDLOG(LOG_ERR,"%s: nyx_charger_query_event returned with error : %d",__func__,err); } handle_charger_event(new_event); }
/** * @brief State "inserted". */ static BatteryState StateInserted(void) { battery_search(false); if (battery_authenticate()) { return kBatteryAuthentic; } else { POWERDLOG(LOG_CRIT,"Battery authentication failure"); return kBatteryNotAuthentic; } }
void battery_read(nyx_battery_status_t *status) { if(battDev == NULL) return; nyx_error_t err = nyx_battery_query_battery_status(battDev,status); if(err != NYX_ERROR_NONE) { POWERDLOG(LOG_ERR,"%s: nyx_battery_query_battery_status returned with error : %d",__func__,err); return; } }
bool chargerDisableCharging(void) { nyx_charger_status_t status; nyx_error_t err = nyx_charger_disable_charging(nyxDev,&status); if(err != NYX_ERROR_NONE) { POWERDLOG(LOG_ERR,"%s: nyx_charger_disable_charging returned with error : %d",__func__,err); } battery_set_wakeup_percentage(false,false); return true; }
int battery_get_ctia_params(void) { if(!battDev) return -1; nyx_error_t err = nyx_battery_get_ctia_parameters(battDev,&battery_ctia_params); if(err != NYX_ERROR_NONE) { POWERDLOG(LOG_ERR,"%s: nyx_battery_get_charge_parameters returned with error : %d",__func__,err); return -1; } return 0; }
bool chargerEnableCharging(int *max_charging_current) { nyx_charger_status_t status; nyx_error_t err = nyx_charger_enable_charging(nyxDev,&status); if(err != NYX_ERROR_NONE) { POWERDLOG(LOG_ERR,"%s: nyx_charger_enable_charging returned with error : %d",__func__,err); return false; } *max_charging_current = currStatus.charger_max_current; battery_set_wakeup_percentage(true,false); return true; }
bool fakeBatteryStatus(LSHandle *sh, LSMessage *message, void *user_data) { /* Ignore the successful registration. */ if (strcmp(LSMessageGetMethod(message), LUNABUS_SIGNAL_REGISTERED) == 0) { return true; } const char *payload = LSMessageGetPayload(message); struct json_object *object = json_tokener_parse(payload); if (is_error(object)) { goto end; } int percent; int temp_C; int current_mA; int voltage_mV; float capacity_mAh; percent = json_object_get_int( json_object_object_get(object, "percent")); temp_C = json_object_get_int( json_object_object_get(object, "temperature_C")); current_mA = json_object_get_int( json_object_object_get(object, "current_mA")); voltage_mV = json_object_get_int( json_object_object_get(object, "voltage_mV")); capacity_mAh = json_object_get_double( json_object_object_get(object, "capacity_mAh")); if(!BatteryDummyValues(percent,temp_C,current_mA,voltage_mV,capacity_mAh)) { POWERDLOG(LOG_ERR,"Unable to load fake battery values"); } g_debug("%s %f mAh, P: %d%%, T: %d C, C: %d mA, V: %d mV", __FUNCTION__,capacity_mAh,percent,temp_C, current_mA, voltage_mV); end: if (!is_error(object)) json_object_put(object); return true; }
static BatteryState StateDebounce(void) { static int debounce_bad = 0; nyx_battery_status_t battery; battery_read(&battery); if (battery.present) { debounce_bad = 0; return kBatteryInserted; } else if (++debounce_bad > BAD_SAMPLES_THRESHOLD) { POWERDLOG(LOG_INFO, "Battery has been removed.\n"); battery_search(true); return kBatteryRemoved; } return kBatteryLast; }
/** * @brief Add a new alarm based on calender time. Sets the callback function based on the "subscribe" option value. */ static bool alarmAddCalendar(LSHandle *sh, LSMessage *message, void *ctx) { struct json_object *object=NULL; object = json_tokener_parse(LSMessageGetPayload(message)); if ( is_error(object) ) { goto malformed_json; } struct json_object *subscribe_json = json_object_object_get(object, "subscribe"); bool subscribe = json_object_get_boolean(subscribe_json); LSMessageRef(message); if(subscribe) { struct context *alrm_ctx=NULL; alrm_ctx = malloc(sizeof(struct context)); if(!alrm_ctx) goto error; memset(alrm_ctx,0,sizeof(struct context)); alrm_ctx->replyMessage = message; LSCall(GetLunaServiceHandle(), "palm://com.palm.sleep/time/alarmAddCalender", LSMessageGetPayload(message), alarms_timeout_subscribe_cb, (void *)alrm_ctx, &alrm_ctx->call_token, NULL); } else LSCallOneReply(GetLunaServiceHandle(), "palm://com.palm.sleep/time/alarmAddCalender", LSMessageGetPayload(message), alarms_timeout_cb, (void *)message, NULL, NULL); goto cleanup; malformed_json: LSMessageReplyErrorBadJSON(sh, message); goto cleanup; error: POWERDLOG(LOG_ERR,"Failed to allocate memory"); LSMessageReplyErrorUnknown(sh, message); cleanup: if (!is_error(object)) json_object_put(object); return true; }
void timesaver_save() { if (NULL == time_db) { // This can happen if we goto ls_error in main() g_warning("%s called with time database name (time_db) uninitialized", __FUNCTION__); goto cleanup; } // First write the contents to tmp file and then rename to "time_saver" file // to ensure file integrity with power cut or battery pull. int file = open(time_db_tmp, O_CREAT | O_WRONLY, S_IRWXU | S_IRGRP | S_IROTH); if (!file) { g_warning("%s: Could not save time to \"%s\"", __FUNCTION__, time_db_tmp); goto cleanup; } struct timespec tp; clock_gettime(CLOCK_REALTIME, &tp); POWERDLOG(LOG_DEBUG, "%s Saving to file %ld", __FUNCTION__, tp.tv_sec); char timestamp[16]; sprintf(timestamp,"%ld", tp.tv_sec); write(file,timestamp,strlen(timestamp)); fsync(file); close(file); int ret = rename(time_db_tmp,time_db); if (ret) { g_warning("%s : Unable to rename %s to %s",__FUNCTION__,time_db_tmp,time_db); } unlink(time_db_tmp); cleanup: return; }
void machineShutdown(void) { char *payload = g_strdup_printf("{\"reason\":\"Battery level is critical\"}"); LSError lserror; LSErrorInit(&lserror); POWERDLOG(LOG_DEBUG,"%s: Sending payload : %s",__func__,payload); bool retVal = LSSignalSend(GetLunaServiceHandle(), "luna://com.palm.power/shutdown/machineOff", payload, &lserror); g_free(payload); if (!retVal) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } }
static void timesaver_restore(time_t secs_since_epoch) { if (secs_since_epoch) { struct timespec tp; tp.tv_sec = secs_since_epoch; tp.tv_nsec = 0; clock_settime(CLOCK_REALTIME, &tp); struct tm time; gmtime_r(&tp.tv_sec, &time); POWERDLOG(LOG_INFO, "%s Setting the time to be " "%02d-%02d-%04d %02d:%02d:%02d", __FUNCTION__, time.tm_mon+1, time.tm_mday, time.tm_year+1900, time.tm_hour, time.tm_min, time.tm_sec); } }
void sendChargerStatus(void) { nyx_charger_status_t status; if(!nyxDev) return; nyx_error_t err = nyx_charger_query_charger_status(nyxDev,&status); if(err != NYX_ERROR_NONE) { POWERDLOG(LOG_ERR,"%s: nyx_charger_query_charger_status returned with error : %d",__func__,err); } POWERDLOG(LOG_DEBUG,"In %s connected : %d:%d, powered : %d:%d",__func__,currStatus.connected,status.connected,currStatus.powered,status.powered); if(currStatus.connected != status.connected || currStatus.powered != status.powered) { LSError lserror; LSErrorInit(&lserror); char *payload = g_strdup_printf("{\"DockConnected\":%s,\"DockPower\":%s,\"DockSerialNo\":\"%s\"," "\"USBConnected\":%s,\"USBName\":\"%s\",\"Charging\":%s}",(status.connected & NYX_CHARGER_INDUCTIVE_CONNECTED) ? "true" : "false", (status.powered & NYX_CHARGER_INDUCTIVE_POWERED) ? "true" :"false",(strlen(status.dock_serial_number)) ? status.dock_serial_number : "NULL", (status.powered & NYX_CHARGER_USB_POWERED) ? "true" : "false",ChargerNameToString(status.connected), (status.is_charging) ? "true":"false"); POWERDLOG(LOG_DEBUG,"%s: Sending payload : %s",__func__,payload); bool retVal = LSSignalSend(GetLunaServiceHandle(), "luna://com.palm.powerd/com/palm/power/USBDockStatus", payload, &lserror); if (!retVal) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); g_free(payload); return; } g_free(payload); payload = g_strdup_printf("{\"type\":\"%s\",\"name\":\"%s\",\"connected\":%s,\"current_mA\":%d,\"message_source\":\"powerd\"}", ChargerTypeToString(status.powered), ChargerNameToString(status.connected), status.connected ? "true" : "false", status.charger_max_current); POWERDLOG(LOG_DEBUG,"%s: Sending payload : %s",__func__,payload); retVal = LSSignalSend(GetLunaServiceHandle(), "luna://com.palm.powerd/com/palm/power/chargerStatus", payload, &lserror); if (!retVal) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } g_free(payload); } if(currStatus.connected != status.connected) { char *payload = g_strdup_printf("{\"connected\":%s}", status.connected ? "true" : "false"); LSError lserror; LSErrorInit(&lserror); POWERDLOG(LOG_DEBUG,"%s: Sending payload : %s",__func__,payload); bool retVal = LSSignalSend(GetLunaServiceHandle(), "luna://com.palm.power/com/palm/power/chargerConnected", payload, &lserror); g_free(payload); if (!retVal) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } } memcpy(&currStatus,&status,sizeof(nyx_charger_status_t)); // Iterate through both charging as well as battery state machines. Is this required ?? // ChargingLogicUpdate(NYX_NO_NEW_EVENT); return; }