blob: 979395d2199462db66fbcccaf2929e9d52e2c076 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* Copyright (c) 2018 Vikrant More
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "console/console.h"
#include "hal/hal_gpio.h"
#include "mesh/mesh.h"
#include "app_gpio.h"
#include "storage.h"
#include "ble_mesh.h"
#include "device_composition.h"
#include "no_transition_work_handler.h"
#include "publisher.h"
#include "state_binding.h"
#include "transition.h"
static bool reset;
static void light_default_var_init(void)
{
gen_def_trans_time_srv_user_data.tt = 0x00;
gen_power_onoff_srv_user_data.onpowerup = STATE_DEFAULT;
light_lightness_srv_user_data.light_range_min = LIGHTNESS_MIN;
light_lightness_srv_user_data.light_range_max = LIGHTNESS_MAX;
light_lightness_srv_user_data.last = LIGHTNESS_MAX;
light_lightness_srv_user_data.def = LIGHTNESS_MAX;
/* Following 2 values are as per specification */
light_ctl_srv_user_data.temp_range_min = TEMP_MIN;
light_ctl_srv_user_data.temp_range_max = TEMP_MAX;
light_ctl_srv_user_data.temp_def = TEMP_MIN;
light_ctl_srv_user_data.lightness_temp_last =
(uint32_t) ((LIGHTNESS_MAX << 16) | TEMP_MIN);
}
static void light_default_status_init(void)
{
uint16_t lightness;
lightness = (uint16_t) (light_ctl_srv_user_data.lightness_temp_last >> 16);
if (lightness) {
gen_onoff_srv_root_user_data.onoff = STATE_ON;
} else {
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
}
/* Retrieve Default Lightness & Temperature Values */
if (light_ctl_srv_user_data.lightness_temp_def) {
light_ctl_srv_user_data.lightness_def = (uint16_t)
(light_ctl_srv_user_data.lightness_temp_def >> 16);
light_ctl_srv_user_data.temp_def = (uint16_t)
(light_ctl_srv_user_data.lightness_temp_def);
}
light_lightness_srv_user_data.def =
light_ctl_srv_user_data.lightness_def;
light_ctl_srv_user_data.temp = light_ctl_srv_user_data.temp_def;
/* Retrieve Range of Lightness & Temperature */
if (light_lightness_srv_user_data.lightness_range) {
light_lightness_srv_user_data.light_range_max = (uint16_t)
(light_lightness_srv_user_data.lightness_range >> 16);
light_lightness_srv_user_data.light_range_min = (uint16_t)
(light_lightness_srv_user_data.lightness_range);
}
if (light_ctl_srv_user_data.temperature_range) {
light_ctl_srv_user_data.temp_range_max = (uint16_t)
(light_ctl_srv_user_data.temperature_range >> 16);
light_ctl_srv_user_data.temp_range_min = (uint16_t)
(light_ctl_srv_user_data.temperature_range);
}
switch (gen_power_onoff_srv_user_data.onpowerup) {
case STATE_OFF:
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
state_binding(ONOFF, ONOFF_TEMP);
break;
case STATE_DEFAULT:
gen_onoff_srv_root_user_data.onoff = STATE_ON;
state_binding(ONOFF, ONOFF_TEMP);
break;
case STATE_RESTORE:
light_lightness_srv_user_data.last = (uint16_t)
(light_ctl_srv_user_data.lightness_temp_last >> 16);
light_ctl_srv_user_data.temp =
(uint16_t) (light_ctl_srv_user_data.lightness_temp_last);
state_binding(ONPOWERUP, ONOFF_TEMP);
break;
}
default_tt = gen_def_trans_time_srv_user_data.tt;
}
void update_light_state(void)
{
uint8_t power, color;
power = 100 * ((float) lightness / 65535);
color = 100 * ((float) (temperature + 32768) / 65535);
printk("power-> %d, color-> %d\n", power, color);
if (lightness) {
/* LED1 On */
hal_gpio_write(led_device[0], 0);
} else {
/* LED1 Off */
hal_gpio_write(led_device[0], 1);
}
if (power < 50) {
/* LED3 On */
hal_gpio_write(led_device[2], 0);
} else {
/* LED3 Off */
hal_gpio_write(led_device[2], 1);
}
if (color < 50) {
/* LED4 On */
hal_gpio_write(led_device[3], 0);
} else {
/* LED4 Off */
hal_gpio_write(led_device[3], 1);
}
if (*ptr_counter == 0 || reset == false) {
reset = true;
os_callout_reset(&no_transition_work, 0);
}
}
static void short_time_multireset_bt_mesh_unprovisioning(void)
{
if (reset_counter >= 4) {
reset_counter = 0;
printk("BT Mesh reset\n");
bt_mesh_reset();
} else {
printk("Reset Counter -> %d\n", reset_counter);
reset_counter++;
}
save_on_flash(RESET_COUNTER);
}
static void reset_counter_timer_handler(struct os_event *dummy)
{
reset_counter = 0;
save_on_flash(RESET_COUNTER);
printk("Reset Counter set to Zero\n");
}
struct os_callout reset_counter_timer;
static void init_timers(void)
{
os_callout_init(&reset_counter_timer, os_eventq_dflt_get(),
reset_counter_timer_handler, NULL);
os_callout_reset(&reset_counter_timer,
os_time_ms_to_ticks32(K_MSEC(7000)));
no_transition_work_init();
}
void bt_initialized(void)
{
light_default_status_init();
update_light_state();
randomize_publishers_TID();
short_time_multireset_bt_mesh_unprovisioning();
}
int
mynewt_main(int argc, char **argv)
{
/* Initialize OS */
sysinit();
light_default_var_init();
app_gpio_init();
init_timers();
transition_timers_init();
init_pub();
ps_settings_init();
printk("Initializing...\n");
/* Initialize the NimBLE host configuration. */
ble_hs_cfg.reset_cb = blemesh_on_reset;
ble_hs_cfg.sync_cb = blemesh_on_sync;
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
return 0;
}