<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Problems related to nrf5340 brighton/off</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/119822/problems-related-to-nrf5340-brighton-off</link><description>Hello. We are testing nrf5340 - nrf7002 using the example of blpovisioning. I try to put on/off function using button, but if I reset pcb and turn on, it will connect to wifi and tcp server normally, but if I turn on -&amp;gt; off -&amp;gt; an error occurred in bt</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 19 Mar 2025 07:16:10 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/119822/problems-related-to-nrf5340-brighton-off" /><item><title>RE: Problems related to nrf5340 brighton/off</title><link>https://devzone.nordicsemi.com/thread/527944?ContentTypeID=1</link><pubDate>Wed, 19 Mar 2025 07:16:10 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:53798f22-43c5-418d-a3cd-f77e91d66ac4</guid><dc:creator>Simonr</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;So the error you&amp;#39;re looking for here seems to come from the arp.c file in&amp;nbsp;&lt;strong&gt;...\v2.9.0\zephyr\subsys\net\l2\ethernet\arp.c&amp;nbsp;&lt;/strong&gt;In the net_pkt() function it seems to check if the destination IP is specified, and returns the &amp;quot;Gateway not set for iface&amp;quot; error if it is not specified.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;struct net_pkt *net_arp_prepare(struct net_pkt *pkt,
				struct in_addr *request_ip,
				struct in_addr *current_ip)
{
	bool is_ipv4_ll_used = false;
	struct arp_entry *entry;
	struct in_addr *addr;

	if (!pkt || !pkt-&amp;gt;buffer) {
		return NULL;
	}

	if (net_pkt_ipv4_acd(pkt)) {
		return arp_prepare(net_pkt_iface(pkt), request_ip, NULL,
				   pkt, current_ip);
	}

	if (IS_ENABLED(CONFIG_NET_IPV4_AUTO)) {
		is_ipv4_ll_used = net_ipv4_is_ll_addr((struct in_addr *)
						&amp;amp;NET_IPV4_HDR(pkt)-&amp;gt;src) ||
				  net_ipv4_is_ll_addr((struct in_addr *)
						&amp;amp;NET_IPV4_HDR(pkt)-&amp;gt;dst);
	}

	/* Is the destination in the local network, if not route via
	 * the gateway address.
	 */
	if (!current_ip &amp;amp;&amp;amp; !is_ipv4_ll_used &amp;amp;&amp;amp;
	    !net_if_ipv4_addr_mask_cmp(net_pkt_iface(pkt), request_ip)) {
		struct net_if_ipv4 *ipv4 = net_pkt_iface(pkt)-&amp;gt;config.ip.ipv4;

		if (ipv4) {
			addr = &amp;amp;ipv4-&amp;gt;gw;
			if (net_ipv4_is_addr_unspecified(addr)) {
				NET_ERR(&amp;quot;Gateway not set for iface %p&amp;quot;,
					net_pkt_iface(pkt));

				return NULL;
			}
		} else {
			addr = request_ip;
		}
	} else {
		addr = request_ip;
	}

	k_mutex_lock(&amp;amp;arp_mutex, K_FOREVER);

	/* If the destination address is already known, we do not need
	 * to send any ARP packet.
	 */
	entry = arp_entry_find_move_first(net_pkt_iface(pkt), addr);
	if (!entry) {
		struct net_pkt *req;

		entry = arp_entry_find_pending(net_pkt_iface(pkt), addr);
		if (!entry) {
			/* No pending, let&amp;#39;s try to get a new entry */
			entry = arp_entry_get_free();
			if (!entry) {
				/* Then let&amp;#39;s take one from table? */
				entry = arp_entry_get_last_from_table();
			}
		} else {
			/* There is a pending ARP request already, check if this packet is already
			 * in the pending list and if so, resend the request, otherwise just
			 * append the packet to the request fifo list.
			 */
			if (k_queue_unique_append(&amp;amp;entry-&amp;gt;pending_queue._queue,
						  net_pkt_ref(pkt))) {
				NET_DBG(&amp;quot;Pending ARP request for %s, queuing pkt %p&amp;quot;,
					net_sprint_ipv4_addr(addr), pkt);
				k_mutex_unlock(&amp;amp;arp_mutex);
				return NULL;
			}

			entry = NULL;
		}

		req = arp_prepare(net_pkt_iface(pkt), addr, entry, pkt,
				  current_ip);

		if (!entry) {
			/* We cannot send the packet, the ARP cache is full
			 * or there is already a pending query to this IP
			 * address, so this packet must be discarded.
			 */
			NET_DBG(&amp;quot;Resending ARP %p&amp;quot;, req);
		}

		if (!req &amp;amp;&amp;amp; entry) {
			/* Add the arp entry back to arp_free_entries, to avoid the
			 * arp entry is leak due to ARP packet allocated failed.
			 */
			sys_slist_prepend(&amp;amp;arp_free_entries, &amp;amp;entry-&amp;gt;node);
		}

		k_mutex_unlock(&amp;amp;arp_mutex);
		return req;
	}

	k_mutex_unlock(&amp;amp;arp_mutex);

	net_pkt_lladdr_src(pkt)-&amp;gt;addr =
		(uint8_t *)net_if_get_link_addr(entry-&amp;gt;iface)-&amp;gt;addr;
	net_pkt_lladdr_src(pkt)-&amp;gt;len = sizeof(struct net_eth_addr);

	net_pkt_lladdr_dst(pkt)-&amp;gt;addr = (uint8_t *)&amp;amp;entry-&amp;gt;eth;
	net_pkt_lladdr_dst(pkt)-&amp;gt;len = sizeof(struct net_eth_addr);

	NET_DBG(&amp;quot;ARP using ll %s for IP %s&amp;quot;,
		net_sprint_ll_addr(net_pkt_lladdr_dst(pkt)-&amp;gt;addr,
				   sizeof(struct net_eth_addr)),
		net_sprint_ipv4_addr(&amp;amp;NET_IPV4_HDR(pkt)-&amp;gt;dst));

	return pkt;
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I added a snippet from&amp;nbsp; NCS 2.9.0 here. How do you set the IP address in your application exactly?&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Simon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Problems related to nrf5340 brighton/off</title><link>https://devzone.nordicsemi.com/thread/527411?ContentTypeID=1</link><pubDate>Fri, 14 Mar 2025 15:06:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:806cdbcc-72ac-4ba3-972c-a24319f1ea40</guid><dc:creator>ozoz05</dc:creator><description>&lt;p&gt;&lt;span&gt;Link in the example referenced: &lt;a href="https://github.com/zephyrproject-rtos/zephyr/pull/70162"&gt;github.com/.../70162&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;main.c&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="text"&gt;#include &amp;lt;zephyr/logging/log.h&amp;gt;
LOG_MODULE_REGISTER(Provisioning, CONFIG_LOG_DEFAULT_LEVEL);

#include &amp;lt;stdlib.h&amp;gt;

#include &amp;lt;zephyr/kernel.h&amp;gt;
#include &amp;lt;zephyr/drivers/i2c.h&amp;gt;
#include &amp;lt;zephyr/device.h&amp;gt;
#include &amp;lt;zephyr/drivers/gpio.h&amp;gt;
#include &amp;lt;zephyr/drivers/mfd/npm1300.h&amp;gt;
#include &amp;lt;zephyr/drivers/sensor.h&amp;gt;
#include &amp;lt;zephyr/drivers/led.h&amp;gt;

#include &amp;quot;Algo/TCP_Client.h&amp;quot;
#include &amp;quot;Algo/Provisioning.h&amp;quot;
#include &amp;quot;Algo/ADC.h&amp;quot;
#include &amp;quot;Algo/fuel_gauge.h&amp;quot;

#include &amp;quot;Algo/deviceInformation.h&amp;quot;

#define SLEEP_TIME_MS 1000

static const struct device *pmic = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_pmic));
static const struct device *charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_charger));
static const struct device *leds = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_leds));
static volatile bool vbus_connected;

#define NPM1300_CHARGER_BASE        0x03U
#define REG_BCHGDISABLESET_OFFSET   0x6
#define BCHGDISABLE_NTC_MASK        BIT(1)

// VBUS 관련 레지스터 주소 정의
#define NPM1300_VBUS_BASE           0x02U       // VBUS 베이스 주소
#define VBUS_OFFSET_STATUS          0x07U       // VBUS 상태 플래그가 포함된 오프셋

// VBUSINSTATUS 레지스터의 비트 정의
#define VBUS_DETECTED_BIT     (1 &amp;lt;&amp;lt; 0)  // Bit 0: VBUS detected
#define VBUS_OVERVOLTAGE_BIT  (1 &amp;lt;&amp;lt; 2)  // Bit 2: Overvoltage protection active
#define VBUS_UNDERVOLTAGE_BIT (1 &amp;lt;&amp;lt; 3)  // Bit 3: Undervoltage detected

// SHIP Mode Base Address
#define SHIP_MODE_BASE       0x0BU

// SHIP Mode 관련 레지스터 오프셋
#define TASKENTERSHIPMODE    0x02U  // Ship Mode 진입 명령


// Button
#define POWER_ON_THRESHOLD_MS 3000  // 3초 이상 눌릴 때 POWER ON 로그
#define LONG_PRESS_THRESHOLD_MS 7000 // 7초 이상 눌릴 때 LONG PRESS 로그

/** &amp;#128994; `button0`을 DT_NODELABEL로 정의 */
static const struct gpio_dt_spec button0 = GPIO_DT_SPEC_GET_OR(DT_NODELABEL(button0), gpios, {0});
static struct gpio_callback button_cb_data;
static struct k_timer button_timer;

volatile bool button_pressed = false;
static bool power_on_logged = false;  // 3초 로그 중복 방지
static bool long_press_logged = false;  // 7초 로그 중복 방지
static int64_t button_press_start_time = 0;  // 버튼이 눌린 시작 시간

//Power Mode
#define Power_Default           0
#define Power_Off           1
#define Power_On            2
#define Power_DeepSleep     3
#define Power_LightSleep    4

static int powerMode = Power_Default;

bool poweron_initialized = false;
bool poweroff_initialized = false;

/** &amp;#128293; 버튼이 3초, 7초 이상 눌린 경우 실행되는 콜백 */
void button_hold_check(struct k_timer *timer_id) {
    if (button_pressed) {
        int64_t elapsed_time = k_uptime_get() - button_press_start_time;

        if (elapsed_time &amp;gt;= POWER_ON_THRESHOLD_MS &amp;amp;&amp;amp; !power_on_logged) {
            LOG_INF(&amp;quot;⚡ POWER ON! Button held for %d ms&amp;quot;, POWER_ON_THRESHOLD_MS);
            power_on_logged = true;
        }
        
        if (elapsed_time &amp;gt;= LONG_PRESS_THRESHOLD_MS &amp;amp;&amp;amp; !long_press_logged) {
            LOG_INF(&amp;quot;&amp;#128308; LONG PRESS DETECTED (Button held for %d ms)&amp;quot;, LONG_PRESS_THRESHOLD_MS);
            long_press_logged = true;
        }
    }
}

/** &amp;#128994; 버튼 인터럽트 핸들러 */
static void button_event_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
    if (pins &amp;amp; BIT(button0.pin)) {
        int val = gpio_pin_get_dt(&amp;amp;button0);

        if (val) {
            /* &amp;#128994; 버튼이 눌렸을 때 */
            button_pressed = true;
            power_on_logged = false;
            long_press_logged = false;
            button_press_start_time = k_uptime_get();  // 버튼이 눌린 시간 기록
            LOG_INF(&amp;quot;&amp;#128309; Button Pressed! Timer Started...&amp;quot;);
            k_timer_start(&amp;amp;button_timer, K_MSEC(100), K_MSEC(100));  // 100ms마다 체크

        } else {
            /* ⚫ 버튼이 떼어졌을 때 */
            button_pressed = false;
            k_timer_stop(&amp;amp;button_timer);
            LOG_INF(&amp;quot;⚫ Button Released! Timer Reset.&amp;quot;);

            if((power_on_logged == true) &amp;amp;&amp;amp; ((powerMode == Power_Off) || (powerMode == Power_Default)))
            {
                LOG_INF(&amp;quot;       POWER ON       &amp;quot;);
                powerMode = Power_On;
            }
            else if((power_on_logged == true) &amp;amp;&amp;amp; (powerMode == Power_On))
            {
                LOG_INF(&amp;quot;       POWER OFF       &amp;quot;);
                powerMode = Power_Off;
            }
        }
    }
}

/** &amp;#128994; 버튼 초기화 함수 */
void button_init(void) {
    int ret;

    if (!gpio_is_ready_dt(&amp;amp;button0)) {
        LOG_ERR(&amp;quot;Error: Button device %s is not ready&amp;quot;, button0.port-&amp;gt;name);
        return;
    }

    ret = gpio_pin_configure_dt(&amp;amp;button0, GPIO_INPUT);
    if (ret != 0) {
        LOG_ERR(&amp;quot;Error %d: Failed to configure button pin&amp;quot;, ret);
        return;
    }

    /* &amp;#128994; 눌릴 때와 뗄 때 모두 인터럽트 발생 */
    ret = gpio_pin_interrupt_configure_dt(&amp;amp;button0, GPIO_INT_EDGE_BOTH);
    if (ret != 0) {
        LOG_ERR(&amp;quot;Error %d: Failed to configure interrupt on button&amp;quot;, ret);
        return;
    }

    gpio_init_callback(&amp;amp;button_cb_data, button_event_callback, BIT(button0.pin));
    gpio_add_callback(button0.port, &amp;amp;button_cb_data);

    /* 타이머 초기화 */
    k_timer_init(&amp;amp;button_timer, button_hold_check, NULL);

    LOG_INF(&amp;quot;Button initialized successfully&amp;quot;);
}

// SHIP Mode 진입 함수
int enter_ship_mode(void) {
    int ret = mfd_npm1300_reg_write(pmic, SHIP_MODE_BASE, TASKENTERSHIPMODE, 1U);
    if (ret == 0) {
        printf(&amp;quot;Device is entering Ship Mode...\n&amp;quot;);
    } else {
        printf(&amp;quot;Failed to enter Ship Mode. Error: %d\n&amp;quot;, ret);
    }
}


// VBUS 상태 확인 함수
int check_vbus_status(void) {
    int ret;
    uint8_t vbus_status;

    // VBUS 상태 레지스터 읽기
    ret = mfd_npm1300_reg_read(pmic, NPM1300_VBUS_BASE, VBUS_OFFSET_STATUS, &amp;amp;vbus_status);
    if (ret != 0) {
        return ret; // 읽기 실패 시 오류 코드 반환
    }

    // VBUS 상태 출력
    if (vbus_status &amp;amp; VBUS_DETECTED_BIT) {
        printf(&amp;quot;VBUS detected.\n&amp;quot;);
        vbus_connected = true;
    } else {
        printf(&amp;quot;VBUS not detected.\n&amp;quot;);
        vbus_connected = false;
    }

    if (vbus_status &amp;amp; VBUS_OVERVOLTAGE_BIT) {
        printf(&amp;quot;VBUS overvoltage detected.\n&amp;quot;);
    }

    if (vbus_status &amp;amp; VBUS_UNDERVOLTAGE_BIT) {
        printf(&amp;quot;VBUS undervoltage detected.\n&amp;quot;);
    }
}


/** &amp;#128295; NTC 체크 비활성화 */
void disable_ntc_check(void) {
    int ret;
    uint8_t read_val = 0;

    uint8_t val = read_val | BCHGDISABLE_NTC_MASK;
    ret = mfd_npm1300_reg_write(pmic, NPM1300_CHARGER_BASE, REG_BCHGDISABLESET_OFFSET, val);
    if (ret &amp;lt; 0) {
        LOG_ERR(&amp;quot;ERROR: Failed to write BCHGDISABLESET! (ret=%d)&amp;quot;, ret);
        return;
    }

    LOG_INF(&amp;quot;NTC check disable command sent.&amp;quot;);
}


int main( void ) {
	int err;
	LOG_INF(&amp;quot;npm1300 fuel gauge\n&amp;quot;);

    if (!device_is_ready(pmic)) {
		LOG_INF(&amp;quot;Pmic device not ready.\n&amp;quot;);
		return 0;
	}

	if (!device_is_ready(charger)) {
		LOG_INF(&amp;quot;Charger device not ready.\n&amp;quot;);
		return 0;
	}

	if (fuel_gauge_init(charger) &amp;lt; 0) {
		LOG_INF(&amp;quot;Could not initialise fuel gauge.\n&amp;quot;);
		return 0;
	}

    if (!device_is_ready(leds)) {
		printk(&amp;quot;Error: led device is not ready\n&amp;quot;);
		return 0;
	}

	static struct gpio_callback event_cb;

	err = mfd_npm1300_add_callback(pmic, &amp;amp;event_cb);
	if (err) {
		LOG_INF(&amp;quot;Failed to add pmic callback.\n&amp;quot;);
		return 0;
	}

	/* ✅ 초기 설정 */
    disable_ntc_check();  // &amp;#128313; NTC 체크 비활성화
    button_init();  // &amp;#128313; 버튼 초기화

	LOG_INF(&amp;quot;SC50 device ok\n&amp;quot;);

    // led_on(leds, 0U);
    // led_on(leds, 1U);
    led_off(leds, 1U);

    // ship mode 들어감감
    // check_vbus_status();
    // if(vbus_connected != true) enter_ship_mode();

	while (1) {

        
        if(powerMode == Power_On)
        {
            // LOG_INF(&amp;quot;--------------------------------------------------------&amp;quot;);
            poweroff_initialized = false;

            if(poweron_initialized == false)
            {
                poweron_initialized = true;

                Task_Provisioning_Init();
                Task_TCP_Client_Init();
                Task_ADC_Init();
            }

            /* &amp;#128260; 주기적으로 상태 확인 */
            // check_vbus_status();
            // fuel_gauge_update(charger, vbus_connected);
        }
        else if(powerMode == Power_Off)
        {
            LOG_INF(&amp;quot;Power Off___---&amp;quot;);
            poweron_initialized = false;

            if(poweroff_initialized == false)
            {
                poweroff_initialized = true;

                Task_ADC_Delete();
                Task_TCP_Client_Delete();
                Task_Provisioning_Delete();
            }
        }
        else if(powerMode == Power_DeepSleep)
        {

        }
        else if(powerMode == Power_LightSleep)
        {

        }

            k_msleep(SLEEP_TIME_MS);
        }

	k_sleep( K_FOREVER );
}&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Provisioning.c&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;pre class="ui-code" data-mode="text"&gt;#include &amp;lt;zephyr/logging/log.h&amp;gt;
LOG_MODULE_DECLARE(Provisioning, LOG_LEVEL_DBG);


#include &amp;lt;zephyr/types.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;zephyr/sys/printk.h&amp;gt;
#include &amp;lt;zephyr/kernel.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/bluetooth.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/hci.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/conn.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/uuid.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/gatt.h&amp;gt;

#include &amp;lt;zephyr/net/wifi.h&amp;gt;
#include &amp;lt;zephyr/net/wifi_mgmt.h&amp;gt;
#include &amp;lt;net/wifi_credentials.h&amp;gt;
#include &amp;lt;net/wifi_mgmt_ext.h&amp;gt;

#include &amp;lt;bluetooth/services/wifi_provisioning.h&amp;gt;

#include &amp;quot;Provisioning.h&amp;quot;
#include &amp;quot;deviceInformation.h&amp;quot;

tContext context;

static struct k_thread ProvisioningThread;
#define Provisioning_STACK_SIZE 8*1024
#define Provisioning_PRIORITY 2
K_THREAD_STACK_DEFINE(PROVISIONING_STACK, Provisioning_STACK_SIZE);
static bool provisioning_thread_running = false;


#ifdef CONFIG_WIFI_PROV_ADV_DATA_UPDATE
#define ADV_DATA_UPDATE_INTERVAL      CONFIG_WIFI_PROV_ADV_DATA_UPDATE_INTERVAL
#endif /* CONFIG_WIFI_PROV_ADV_DATA_UPDATE */

#define ADV_PARAM_UPDATE_DELAY        1

#define ADV_DATA_VERSION_IDX          (BT_UUID_SIZE_128 + 0)
#define ADV_DATA_FLAG_IDX             (BT_UUID_SIZE_128 + 1)
#define ADV_DATA_FLAG_PROV_STATUS_BIT BIT(0)
#define ADV_DATA_FLAG_CONN_STATUS_BIT BIT(1)
#define ADV_DATA_RSSI_IDX             (BT_UUID_SIZE_128 + 3)

#define PROV_BT_LE_ADV_PARAM_FAST BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE, \
						BT_GAP_ADV_FAST_INT_MIN_2, \
						BT_GAP_ADV_FAST_INT_MAX_2, NULL)

#define PROV_BT_LE_ADV_PARAM_SLOW BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE, \
						BT_GAP_ADV_SLOW_INT_MIN, \
						BT_GAP_ADV_SLOW_INT_MAX, NULL)

#define ADV_DAEMON_STACK_SIZE 4096
#define ADV_DAEMON_PRIORITY 5

K_THREAD_STACK_DEFINE(adv_daemon_stack_area, ADV_DAEMON_STACK_SIZE);

static struct k_work_q adv_daemon_work_q;

static uint8_t device_name[] = {&amp;#39;P&amp;#39;, &amp;#39;V&amp;#39;, &amp;#39;0&amp;#39;, &amp;#39;0&amp;#39;, &amp;#39;0&amp;#39;, &amp;#39;0&amp;#39;, &amp;#39;0&amp;#39;, &amp;#39;0&amp;#39;};

static uint8_t prov_svc_data[] = {BT_UUID_PROV_VAL, 0x00, 0x00, 0x00, 0x00};

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
	BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_PROV_VAL),
	BT_DATA(BT_DATA_NAME_COMPLETE, device_name, sizeof(device_name)),
};

static const struct bt_data sd[] = {
	BT_DATA(BT_DATA_SVC_DATA128, prov_svc_data, sizeof(prov_svc_data)),
};

static struct k_work_delayable update_adv_param_work;
static struct k_work_delayable update_adv_data_work;

static void restart_network_interface(void) {
    struct net_if *iface = net_if_get_default();

    if (!iface) {
        printk(&amp;quot;❌ No network interface found!\n&amp;quot;);
        return;
    }

    printk(&amp;quot;&amp;#128260; Restarting network interface...\n&amp;quot;);

    net_if_down(iface);
    k_sleep(K_MSEC(500));  
    net_dhcpv4_stop(iface);
    net_if_up(iface);
    k_sleep(K_MSEC(500));
    net_dhcpv4_start(iface);

    printk(&amp;quot;✅ Network interface restarted successfully.\n&amp;quot;);
}

static void update_wifi_status_in_adv(void)
{
	int rc;
	struct net_if *iface = net_if_get_default();
	struct wifi_iface_status status = { 0 };

	prov_svc_data[ADV_DATA_VERSION_IDX] = PROV_SVC_VER;

	/* If no config, mark it as unprovisioned. */
	if (!bt_wifi_prov_state_get()) {
        printk(&amp;quot;No Wi-Fi provisioning data available.\n&amp;quot;);
		prov_svc_data[ADV_DATA_FLAG_IDX] &amp;amp;= ~ADV_DATA_FLAG_PROV_STATUS_BIT;

        memset(&amp;amp;status, 0, sizeof(status));
	} else {
        printk(&amp;quot;Wi-Fi provisioning data found.\n&amp;quot;);
		prov_svc_data[ADV_DATA_FLAG_IDX] |= ADV_DATA_FLAG_PROV_STATUS_BIT;
	}

	rc = net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &amp;amp;status,
				sizeof(status));
	/* If WiFi is not connected or error occurs, mark it as not connected. */
	if ((rc != 0) || (status.state &amp;lt; WIFI_STATE_ASSOCIATED)) {
		context.connected = false;
        printk(&amp;quot;Failed to get Wi-Fi status (err %d). Assuming no connection.\n&amp;quot;, rc);
		prov_svc_data[ADV_DATA_FLAG_IDX] &amp;amp;= ~ADV_DATA_FLAG_CONN_STATUS_BIT;
		prov_svc_data[ADV_DATA_RSSI_IDX] = INT8_MIN;
	} else if (status.state &amp;lt; WIFI_STATE_ASSOCIATED) {
        printk(&amp;quot;Wi-Fi not connected.\n&amp;quot;);
		context.connected = false;
        prov_svc_data[ADV_DATA_FLAG_IDX] &amp;amp;= ~ADV_DATA_FLAG_CONN_STATUS_BIT;
        prov_svc_data[ADV_DATA_RSSI_IDX] = INT8_MIN;
    } else {
        context.connected = true;
        /* Log retrieved Wi-Fi credentials */
        printk(&amp;quot;Wi-Fi Status : Wi-Fi connected.\n&amp;quot;);
        printk(&amp;quot;SSID: %s\n&amp;quot;, status.ssid[0] ? status.ssid : &amp;quot;N/A&amp;quot;);
        printk(&amp;quot;State: %d\n&amp;quot;, status.state);
        printk(&amp;quot;RSSI: %d dBm\n&amp;quot;, status.rssi);
        printk(&amp;quot;Channel: %d\n&amp;quot;, status.channel);
        printk(&amp;quot;BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n&amp;quot;,
           status.bssid[0], status.bssid[1], status.bssid[2],
           status.bssid[3], status.bssid[4], status.bssid[5]);
		/* WiFi is connected. */
		prov_svc_data[ADV_DATA_FLAG_IDX] |= ADV_DATA_FLAG_CONN_STATUS_BIT;
		/* Currently cannot retrieve RSSI. Use a dummy number. */
		prov_svc_data[ADV_DATA_RSSI_IDX] = status.rssi;
	}
}

static void connected(struct bt_conn *conn, uint8_t err)
{
	char addr[BT_ADDR_LE_STR_LEN];

	if (err) {
		printk(&amp;quot;BT Connection failed (err 0x%02x).\n&amp;quot;, err);
		return;
	}

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	printk(&amp;quot;BT Connected: %s&amp;quot;, addr);

	k_work_cancel_delayable(&amp;amp;update_adv_data_work);
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	printk(&amp;quot;BT Disconnected: %s (reason 0x%02x).\n&amp;quot;, addr, reason);

	k_work_reschedule_for_queue(&amp;amp;adv_daemon_work_q, &amp;amp;update_adv_param_work,
				K_SECONDS(ADV_PARAM_UPDATE_DELAY));
	k_work_reschedule_for_queue(&amp;amp;adv_daemon_work_q, &amp;amp;update_adv_data_work, K_NO_WAIT);
}

static void identity_resolved(struct bt_conn *conn, const bt_addr_le_t *rpa,
				const bt_addr_le_t *identity)
{
	char addr_identity[BT_ADDR_LE_STR_LEN];
	char addr_rpa[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(identity, addr_identity, sizeof(addr_identity));
	bt_addr_le_to_str(rpa, addr_rpa, sizeof(addr_rpa));

	printk(&amp;quot;BT Identity resolved %s -&amp;gt; %s.\n&amp;quot;, addr_rpa, addr_identity);
}

static void security_changed(struct bt_conn *conn, bt_security_t level,
				enum bt_security_err err)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	if (!err) {
		printk(&amp;quot;BT Security changed: %s level %u.\n&amp;quot;, addr, level);
	} else {
		printk(&amp;quot;BT Security failed: %s level %u err %d.\n&amp;quot;, addr, level,
			   err);
	}
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = connected,
	.disconnected = disconnected,
	.identity_resolved = identity_resolved,
	.security_changed = security_changed,
};

static void auth_cancel(struct bt_conn *conn)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	printk(&amp;quot;BT Pairing cancelled: %s.\n&amp;quot;, addr);
}

static struct bt_conn_auth_cb auth_cb_display = {
	.cancel = auth_cancel,
};

static void pairing_complete(struct bt_conn *conn, bool bonded)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	printk(&amp;quot;BT pairing completed: %s, bonded: %d\n&amp;quot;, addr, bonded);
}

static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
{
	printk(&amp;quot;BT Pairing Failed (%d). Disconnecting.\n&amp;quot;, reason);
	bt_conn_disconnect(conn, BT_HCI_ERR_AUTH_FAIL);
}

static struct bt_conn_auth_info_cb auth_info_cb_display = {

	.pairing_complete = pairing_complete,
	.pairing_failed = pairing_failed,
};

static void update_adv_data_task(struct k_work *item)
{
	int rc;

	update_wifi_status_in_adv();
	rc = bt_le_adv_update_data(ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
	if (rc != 0) {
		printk(&amp;quot;Cannot update advertisement data, err = %d\n&amp;quot;, rc);
	}
#ifdef CONFIG_WIFI_PROV_ADV_DATA_UPDATE
	k_work_reschedule_for_queue(&amp;amp;adv_daemon_work_q, &amp;amp;update_adv_data_work,
				K_SECONDS(ADV_DATA_UPDATE_INTERVAL));
#endif /* CONFIG_WIFI_PROV_ADV_DATA_UPDATE */
}

static void update_adv_param_task(struct k_work *item)
{
	int rc;

	rc = bt_le_adv_stop();
	if (rc != 0) {
		printk(&amp;quot;Cannot stop advertisement: err = %d\n&amp;quot;, rc);
		return;
	}

	rc = bt_le_adv_start(prov_svc_data[ADV_DATA_FLAG_IDX] &amp;amp; ADV_DATA_FLAG_PROV_STATUS_BIT ?
		PROV_BT_LE_ADV_PARAM_SLOW : PROV_BT_LE_ADV_PARAM_FAST,
		ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
	if (rc != 0) {
		printk(&amp;quot;Cannot start advertisement: err = %d\n&amp;quot;, rc);
	}
}

static void byte_to_hex(char *ptr, uint8_t byte, char base)
{
	int i, val;

	for (i = 0, val = (byte &amp;amp; 0xf0) &amp;gt;&amp;gt; 4; i &amp;lt; 2; i++, val = byte &amp;amp; 0x0f) {
		if (val &amp;lt; 10) {
			*ptr++ = (char) (val + &amp;#39;0&amp;#39;);
		} else {
			*ptr++ = (char) (val - 10 + base);
		}
	}
}

static void update_dev_name(struct net_linkaddr *mac_addr)
{
	byte_to_hex(&amp;amp;device_name[2], mac_addr-&amp;gt;addr[3], &amp;#39;A&amp;#39;);
	byte_to_hex(&amp;amp;device_name[4], mac_addr-&amp;gt;addr[4], &amp;#39;A&amp;#39;);
	byte_to_hex(&amp;amp;device_name[6], mac_addr-&amp;gt;addr[5], &amp;#39;A&amp;#39;);
}


static void print_credential(void *cb_arg, const char *ssid, size_t ssid_len)
{
    struct wifi_credentials_personal creds;
    int ret;

    memset(&amp;amp;creds, 0, sizeof(creds));

    ret = wifi_credentials_get_by_ssid_personal_struct(ssid, ssid_len, &amp;amp;creds);
    if (ret == 0) {
        printk(&amp;quot;-------------------------------\n&amp;quot;);
        printk(&amp;quot;Stored Wi-Fi Credential:\n&amp;quot;);
        printk(&amp;quot;SSID: %s\n&amp;quot;, creds.header.ssid);
        printk(&amp;quot;Security Type: %d\n&amp;quot;, creds.header.type);
        printk(&amp;quot;Password: %s\n&amp;quot;, creds.password);
    } else {
        printk(&amp;quot;Failed to retrieve credentials for SSID: %s (error: %d)\n&amp;quot;, ssid, ret);
    }
}

static void log_stored_wifi_credentials(void)
{
    if (wifi_credentials_is_empty()) {
        printk(&amp;quot;No stored Wi-Fi credentials found.\n&amp;quot;);
    } else {
        wifi_credentials_for_each_ssid(print_credential, NULL);
    }
}


void disconnect_wifi(void) {
    struct net_if *iface = net_if_get_default();
    int rc = net_mgmt(NET_REQUEST_WIFI_DISCONNECT, iface, NULL, 0);

    if (rc == 0) {
        printk(&amp;quot;Wi-Fi disconnected successfully.\n&amp;quot;);

		context.connected = false;
		
        printk(&amp;quot;✅ Bluetooth disabled.\n&amp;quot;);
    } else {
        printk(&amp;quot;Failed to disconnect Wi-Fi (err: %d)\n&amp;quot;, rc);
    }
}
static void disconnect_callback(struct bt_conn *conn, void *data) {
    int err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
    if (err) {
        printk(&amp;quot;⚠️ Failed to disconnect BLE connection (err %d)\n&amp;quot;, err);
    } else {
        printk(&amp;quot;✅ BLE connection disconnected.\n&amp;quot;);
    }
    bt_conn_unref(conn);  // 연결 해제
}

void Task_Provisioning_Delete( void ){
    printk(&amp;quot;&amp;#128308; Task_Provisioning_Delete: Stopping Bluetooth and Wi-Fi.\n&amp;quot;);

    /* ✅ Wi-Fi 연결 해제 */
    disconnect_wifi();

    /* ✅ Work Queue에서 실행 중인 작업 취소 */
    k_work_cancel_delayable(&amp;amp;update_adv_param_work);
    k_work_cancel_delayable(&amp;amp;update_adv_data_work);
    printk(&amp;quot;✅ Work queue tasks canceled.\n&amp;quot;);

    /* ✅ Bluetooth 광고 및 연결 중단 */
    bt_le_adv_stop();
    printk(&amp;quot;✅ Bluetooth advertising stopped.\n&amp;quot;);

    /* ✅ 모든 Bluetooth 연결을 끊음 */
    bt_conn_foreach(BT_CONN_TYPE_ALL, disconnect_callback, NULL);
    k_sleep(K_MSEC(500));  // 안정적인 연결 해제 대기

    /* ✅ HCI Reset 수행 (강제 리셋) */
    // struct net_buf *rsp = NULL;
    // int err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, &amp;amp;rsp);
    // if (err) {
    //     printk(&amp;quot;⚠️ HCI Reset failed (err %d)\n&amp;quot;, err);
    // } else {
    //     printk(&amp;quot;✅ HCI Reset successful.\n&amp;quot;);
    // }
    // if (rsp) {
    //     net_buf_unref(rsp);
    // }
    // k_sleep(K_MSEC(500)); // HCI Reset 후 안정적인 상태 대기
    nrf_reset_network_force_off();
    /* ✅ BLE 기능 완전히 종료 */
    err = bt_disable();
    if (err) {
        printk(&amp;quot;⚠️ Bluetooth disable failed (err %d)\n&amp;quot;, err);
    } else {
        printk(&amp;quot;✅ Bluetooth disabled successfully.\n&amp;quot;);
    }
    k_sleep(K_MSEC(1000)); // Bluetooth 리소스 완전히 해제 대기

    /* ❌ `bt_hci_driver_unregister()` 호출 제거 → Zephyr에서 제공되지 않음 */

    

    /* ✅ Provisioning 쓰레드 중단 */
    if (provisioning_thread_running) {
        k_thread_abort(&amp;amp;ProvisioningThread);
        provisioning_thread_running = false;
        printk(&amp;quot;✅ Provisioning thread aborted.\n&amp;quot;);
    }

    // printk(&amp;quot;&amp;#128308; Task_Provisioning_Delete: Stopping Bluetooth advertising and Wi-Fi.\n&amp;quot;);

    // /* ✅ Work Queue에서 실행 중인 작업 취소 */
    // k_work_cancel_delayable(&amp;amp;update_adv_param_work);
    // k_work_cancel_delayable(&amp;amp;update_adv_data_work);
    // printk(&amp;quot;✅ Work queue tasks canceled.\n&amp;quot;);

    // /* ✅ Bluetooth 광고 중단 */
    // int rc = bt_le_adv_stop();
    // if (rc) {
    //     printk(&amp;quot;⚠️ Bluetooth advertising stop failed (err %d)\n&amp;quot;, rc);
    // } else {
    //     printk(&amp;quot;✅ Bluetooth advertising stopped.\n&amp;quot;);
    // }

    // /* ✅ Wi-Fi 연결 해제 */
    // disconnect_wifi();

    // /* ✅ 기존의 Bluetooth 연결을 모두 끊음 */
    // uint8_t reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN;
    // bt_conn_foreach(BT_CONN_TYPE_ALL, disconnect_callback, &amp;amp;reason);
    // k_sleep(K_MSEC(200)); // 안정적인 연결 해제 대기

    // /* ❌ bt_disable() 제거 */

    // printk(&amp;quot;✅ Task_Provisioning_Delete completed.\n&amp;quot;);

    // printk(&amp;quot;Task_Provisioning_Delete\n&amp;quot;);

    // /* ✅ Work Queue에서 실행 중인 작업 취소 */
    // k_work_cancel_delayable(&amp;amp;update_adv_param_work);
    // k_work_cancel_delayable(&amp;amp;update_adv_data_work);
    // printk(&amp;quot;✅ Work queue tasks canceled.\n&amp;quot;);
	
    // /* ✅ Bluetooth 광고 중단 */
    // bt_le_adv_stop();
    // printk(&amp;quot;✅ Bluetooth advertising stopped.\n&amp;quot;);

    // /* ✅ Wi-Fi 연결 해제 */
    // disconnect_wifi();

    // /* ✅ Bluetooth 종료 (필요한 경우) */
    // bt_disable();
    // k_sleep(K_MSEC(500));  // Bluetooth 종료 후 안정적인 상태로 대기
    // printk(&amp;quot;✅ Bluetooth disabled.\n&amp;quot;);

    // /* ✅ Provisioning 쓰레드 중단 */
    // k_thread_abort(&amp;amp;ProvisioningThread);
    // printk(&amp;quot;✅ Provisioning thread aborted.\n&amp;quot;);
};


int Provisioning(void)
{
    // int rc;
    // struct net_if *iface = net_if_get_default();
    // struct net_linkaddr *mac_addr = net_if_get_link_addr(iface);
    // char device_name_str[sizeof(device_name) + 1];

    // /* Sleep 1 second to allow initialization of Wi-Fi driver */
    // k_sleep(K_SECONDS(1));

    // bt_conn_auth_cb_register(&amp;amp;auth_cb_display);
    // bt_conn_auth_info_cb_register(&amp;amp;auth_info_cb_display);

    // /* ✅ Bluetooth가 이미 활성화된 경우 `bt_enable()`을 실행하지 않음 */
    // if (!bt_is_ready()) {  
    //     int retry = 0;
    //     while (retry &amp;lt; 3) {
    //         rc = bt_enable(NULL);
    //         if (rc == 0) {
    //             printk(&amp;quot;✅ Bluetooth initialized successfully.\n&amp;quot;);
    //             break;
    //         } else if (rc == -11) {
    //             printk(&amp;quot;⚠️ bt_enable() failed with -11. Retrying...\n&amp;quot;);
    //             k_sleep(K_MSEC(500));  // 500ms 대기 후 재시도
    //         } else {
    //             printk(&amp;quot;❌ Bluetooth init failed (err %d)\n&amp;quot;, rc);
    //             return 0;
    //         }
    //         retry++;
    //     }

    //     if (rc != 0) {
    //         printk(&amp;quot;❌ Bluetooth initialization failed after retries.\n&amp;quot;);
    //         return 0;
    //     }
    // } else {
    //     printk(&amp;quot;✅ Bluetooth is already initialized. Skipping bt_enable().\n&amp;quot;);
    // }

    // /* ✅ Wi-Fi Provisioning Service 초기화 */
    // rc = bt_wifi_prov_init();
    // if (rc == 0) {
    //     printk(&amp;quot;✅ Wi-Fi provisioning service started successfully.\n&amp;quot;);
    // } else {
    //     printk(&amp;quot;❌ Error initializing Wi-Fi provisioning service.\n&amp;quot;);
    //     return 0;
    // }

    // /* ✅ Bluetooth Device Name 설정 */
    // if (mac_addr) {
    //     update_dev_name(mac_addr);
    // }
    // device_name_str[sizeof(device_name_str) - 1] = &amp;#39;\0&amp;#39;;
    // memcpy(device_name_str, device_name, sizeof(device_name));
    // bt_set_name(device_name_str);

    // /* ✅ Bluetooth Advertising 시작 */
    // rc = bt_le_adv_start(prov_svc_data[ADV_DATA_FLAG_IDX] &amp;amp; ADV_DATA_FLAG_PROV_STATUS_BIT ?
    //     PROV_BT_LE_ADV_PARAM_SLOW : PROV_BT_LE_ADV_PARAM_FAST,
    //     ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    
    // if (rc) {
    //     printk(&amp;quot;❌ BT Advertising failed to start (err %d)\n&amp;quot;, rc);
    //     return 0;
    // }
    // printk(&amp;quot;✅ BT Advertising successfully started.\n&amp;quot;);

    // /* ✅ Wi-Fi 상태 업%EB%8D%B0이트 */
    // update_wifi_status_in_adv();

    // return 0;
	
    int rc;
    struct net_if *iface = net_if_get_default();
    struct net_linkaddr *mac_addr = net_if_get_link_addr(iface);
    char device_name_str[sizeof(device_name) + 1];

    /* Sleep 1 second to allow initialization of Wi-Fi driver */
    k_sleep(K_SECONDS(1));

    bt_conn_auth_cb_register(&amp;amp;auth_cb_display);
    bt_conn_auth_info_cb_register(&amp;amp;auth_info_cb_display);

    /* ✅ IPC(HCI) 상태 확인 후 Bluetooth 활성화 */
    // int retry = 0;
    // while (retry &amp;lt; 3) {
    //     rc = bt_enable(NULL);
    //     if (rc == 0) {
    //         printk(&amp;quot;✅ Bluetooth initialized successfully.\n&amp;quot;);
    //         break;
    //     } else if (rc == -11) {
    //         printk(&amp;quot;⚠️ bt_enable() failed with -11. Retrying...\n&amp;quot;);
    //         k_sleep(K_MSEC(500));  // 500ms 대기 후 재시도
    //     } else {
    //         printk(&amp;quot;❌ Bluetooth init failed (err %d)\n&amp;quot;, rc);
    //         return 0;
    //     }
    //     retry++;
    // }

    // if (rc != 0) {
    //     printk(&amp;quot;❌ Bluetooth initialization failed after retries.\n&amp;quot;);
    //     return 0;
    // }

    /* ✅ Wi-Fi Provisioning Service 초기화 */
    rc = bt_wifi_prov_init();
    if (rc == 0) {
        printk(&amp;quot;✅ Wi-Fi provisioning service started successfully.\n&amp;quot;);
    } else {
        printk(&amp;quot;❌ Error initializing Wi-Fi provisioning service.\n&amp;quot;);
        return 0;
    }

    /* ✅ Bluetooth Device Name 설정 */
    if (mac_addr) {
        update_dev_name(mac_addr);
    }
    device_name_str[sizeof(device_name_str) - 1] = &amp;#39;\0&amp;#39;;
    memcpy(device_name_str, device_name, sizeof(device_name));
    bt_set_name(device_name_str);

    /* ✅ Bluetooth Advertising 시작 */
    rc = bt_le_adv_start(prov_svc_data[ADV_DATA_FLAG_IDX] &amp;amp; ADV_DATA_FLAG_PROV_STATUS_BIT ?
        PROV_BT_LE_ADV_PARAM_SLOW : PROV_BT_LE_ADV_PARAM_FAST,
        ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    
    if (rc) {
        printk(&amp;quot;❌ BT Advertising failed to start (err %d)\n&amp;quot;, rc);
        return 0;
    }
    printk(&amp;quot;✅ BT Advertising successfully started.\n&amp;quot;);

    /* ✅ Wi-Fi 상태 업데이트 */
    update_wifi_status_in_adv();

    /* ✅ Work Queue 설정 */
    k_work_queue_init(&amp;amp;adv_daemon_work_q);
    k_work_queue_start(&amp;amp;adv_daemon_work_q, adv_daemon_stack_area,
        K_THREAD_STACK_SIZEOF(adv_daemon_stack_area), ADV_DAEMON_PRIORITY,
        NULL);

    k_work_init_delayable(&amp;amp;update_adv_param_work, update_adv_param_task);
    k_work_init_delayable(&amp;amp;update_adv_data_work, update_adv_data_task);

#ifdef CONFIG_WIFI_PROV_ADV_DATA_UPDATE
    k_work_schedule_for_queue(&amp;amp;adv_daemon_work_q, &amp;amp;update_adv_data_work,
        K_SECONDS(ADV_DATA_UPDATE_INTERVAL));
#endif /* CONFIG_WIFI_PROV_ADV_DATA_UPDATE */

    /* ✅ 저장된 Wi-Fi Credentials 적용 */
    net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, NULL, 0);

    /* ✅ DHCP Hostname 설정 */
    char *hostname = &amp;quot;SC50_rev1&amp;quot;;
    rc = net_hostname_set(hostname, strlen(hostname));
    if (rc &amp;lt; 0) {
        printk(&amp;quot;❌ Failed to set hostname: %d\n&amp;quot;, rc);
    } else {
        printk(&amp;quot;✅ Hostname set to: %s\n&amp;quot;, hostname);
    }

    /* ✅ 저장된 Wi-Fi Credentials 로그 출력 */
    log_stored_wifi_credentials();

    return 0;
}



/*! Task_ADC_Init initializes the task ADC
*
* @brief ADC initialization
*/
void Task_Provisioning_Init( void ){
    if (provisioning_thread_running) {
        printk(&amp;quot;⚠️ Provisioning thread already running. Skipping init.\n&amp;quot;);
        return;
    }

    printk(&amp;quot;Task_Provisioning_Init\n&amp;quot;);

    /* ✅ Provisioning 쓰레드 실행 중 상태 설정 */
    provisioning_thread_running = true;

    /* ✅ Bluetooth가 이미 활성화된 경우 실행하지 않음 */
    if (!bt_is_ready()) {  
        int retry = 0;
        int rc;
        while (retry &amp;lt; 3) {
            rc = bt_enable(NULL);
            if (rc == 0) {
                printk(&amp;quot;✅ Bluetooth initialized successfully.\n&amp;quot;);
                break;
            } else if (rc == -11) {
                printk(&amp;quot;⚠️ bt_enable() failed with -11. Retrying... (Attempt %d)\n&amp;quot;, retry + 1);
                k_sleep(K_MSEC(1000));  // 1초 대기 후 재시도
            } else {
                printk(&amp;quot;❌ Bluetooth init failed (err %d)\n&amp;quot;, rc);
                provisioning_thread_running = false; // 초기화 실패 시 다시 실행 가능하도록 설정
                return;
            }
            retry++;
        }

        if (rc != 0) {
            printk(&amp;quot;❌ Bluetooth initialization failed after retries.\n&amp;quot;);
            provisioning_thread_running = false;
            return;
        }
    } else {
        printk(&amp;quot;✅ Bluetooth is already initialized. Skipping bt_enable().\n&amp;quot;);
    }

	k_thread_create	(														
					&amp;amp;ProvisioningThread,										
					PROVISIONING_STACK,										
					Provisioning_STACK_SIZE,									
					(k_thread_entry_t)Provisioning,							
					NULL,													
					NULL,													
					NULL,													
					Provisioning_PRIORITY,									
					0,														
					K_NO_WAIT);	

	 k_thread_name_set(&amp;amp;ProvisioningThread, &amp;quot;Provisioning&amp;quot;);
	 k_thread_start(&amp;amp;ProvisioningThread);
};&lt;/pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;TcpClient.c&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#include &amp;lt;zephyr/logging/log.h&amp;gt;
LOG_MODULE_DECLARE( Provisioning, CONFIG_LOG_DEFAULT_LEVEL );

#include &amp;lt;zephyr/kernel.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;

//#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;zephyr/net/socket.h&amp;gt;
#include &amp;lt;zephyr/net/net_if.h&amp;gt;
#include &amp;lt;zephyr/net/net_ip.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt; 

#include &amp;lt;zephyr/storage/flash_map.h&amp;gt;
#include &amp;lt;zephyr/drivers/flash.h&amp;gt;

#include &amp;lt;zephyr/device.h&amp;gt;
#include &amp;lt;zephyr/devicetree.h&amp;gt;	

#include &amp;quot;TCP_Client.h&amp;quot;
#include &amp;quot;deviceInformation.h&amp;quot;
#include &amp;quot;ADC.h&amp;quot;

uint16_t *adc_fsr_converted = NULL;
size_t adc_fsr_converted_size = 0;
bool fsr_data_flag = false;

//! Stack size for the TCP_CLIENT thread
#define TCP_CLIENT_STACK_SIZE 2*1024
//! TCP_CLIENT thread priority level
#define TCP_CLIENT_PRIORITY 4
//! Time in miliseconds to wait to send the TCP message since the board gets a
// stable IP address
#define TCP_CLIENT_WAIT_TO_SEND_MS 6000

//! TCP Client stack definition
K_THREAD_STACK_DEFINE(TCP_CLIENT_STACK, TCP_CLIENT_STACK_SIZE);
//! Variable to identify the TCP Client thread
static struct k_thread tcpClientThread;

//! TCP message sent by the client.
static uint8_t TCPClientMessage[] = {0xfb, 0xa4, 0xcf, 0x12, 0xa1, 0xe2, 0x6d, 0x53, 0x43, 0x53, 0x43, 0x35, 0x30, 0x41, 0x47, 0xff, 0xfe};

//! Receiver buffer
// static uint8_t receiverBuffer[20];
                                      
static bool context_connected = false;  // Simulated context flag
static bool send_flag = false;
static bool packet_start = false;

FdsData received_tcp_data = {0};  // TCP 데이터 저장 구조체
bool received_tcp_data_flag = false;      // 새 데이터가 들어왔는지 체크하는 플래그

// #define FLASH_DEVICE DT_LABEL(DT_NODELABEL(flash0))   // Flash Device 지정
#define FLASH_DEVICE DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)) // ✅ 수정
#define FLASH_STORAGE_OFFSET FLASH_AREA_OFFSET(storage)
#define FLASH_STORAGE_SIZE   FLASH_AREA_SIZE(storage)


// ✅ 기본값 (초기값 설정)
#define DEFAULT_SPEED  0x64
#define DEFAULT_AMP    0x80
#define DEFAULT_SENS   0xFF
#define DEFAULT_RES3   0x01

static int tcpClientSocket = -1;  // ✅ TCP 소켓 핸들을 전역 변수로 선언


// Flash에서 데이터 읽어오기
void flash_load_data(void) {
    const struct device *flash_dev = FLASH_DEVICE;
    if (!device_is_ready(flash_dev)) {
        printk(&amp;quot;Flash device not ready!\n&amp;quot;);
        return;
    }

    // Flash에서 데이터 읽기
    int err = flash_read(flash_dev, FLASH_STORAGE_OFFSET, &amp;amp;received_tcp_data, sizeof(received_tcp_data));

    if (err != 0 || received_tcp_data.speed == 0xFFFFFFFF) {  // Flash 데이터가 없거나 초기화되지 않은 경우 // Falsh에 데이터가 없으면 기본적으로 0xFFFFFFFF으로 되어 있고, 구조체 첫번째 인자만 확인으로 판별할 수 있음
        printk(&amp;quot;Flash data not found! Saving default values...\n&amp;quot;);

        flash_save_data(0, DEFAULT_SPEED);
        flash_save_data(1, DEFAULT_AMP);
        flash_save_data(2, DEFAULT_SENS);
        flash_save_data(3, DEFAULT_RES3);
    } else {
        printk(&amp;quot;Loaded Flash Data -&amp;gt; SPEED: %d, AMP: %d, SENS: %d, RES3: %d\n&amp;quot;,
               received_tcp_data.speed, received_tcp_data.amp, received_tcp_data.sens, received_tcp_data.res3);
    }
}


// Flash 데이터 저장
void flash_save_data(int field, uint32_t value) {
    const struct device *flash_dev = FLASH_DEVICE;
    if (!device_is_ready(flash_dev)) {
        printk(&amp;quot;Flash device not ready!\n&amp;quot;);
        return;
    }

    // ✅ 특정 필드 값만 변경 (구조체 순서 기반)
    uint32_t *fields[] = {
        &amp;amp;received_tcp_data.speed,  // 0
        &amp;amp;received_tcp_data.amp,    // 1
        &amp;amp;received_tcp_data.sens,   // 2
        &amp;amp;received_tcp_data.res3    // 3
    };

    if (field &amp;lt; 0 || field &amp;gt;= (sizeof(fields) / sizeof(fields[0]))) {
        printk(&amp;quot;Invalid field index: %d\n&amp;quot;, field);
        return;
    }

    *fields[field] = value;

    // Flash에 기존 데이터 삭제 후 저장
    flash_erase(flash_dev, FLASH_STORAGE_OFFSET, FLASH_STORAGE_SIZE);
    int err = flash_write(flash_dev, FLASH_STORAGE_OFFSET, &amp;amp;received_tcp_data, sizeof(received_tcp_data));

    if (err != 0) {
        printk(&amp;quot;Flash write failed: %d\n&amp;quot;, err);
    } else {
        printk(&amp;quot;Flash Saved Data -&amp;gt; SPEED: %d, AMP: %d, SENS: %d, RES3: %d\n&amp;quot;,
               received_tcp_data.speed, received_tcp_data.amp, received_tcp_data.sens, received_tcp_data.res3);
    }
}


void close_socket(int *socket_fd) {
    if (*socket_fd &amp;gt;= 0) {
        shutdown(*socket_fd, SHUT_RDWR);  // 소켓 완전 종료
        k_msleep(100);  // 소켓 정리 후 약간의 대기
        close(*socket_fd);
        *socket_fd = -1;
        LOG_INF(&amp;quot;Socket closed.&amp;quot;);
    }
}


void configure_static_ip(void) {
    struct net_if *iface = net_if_get_default();
    struct in_addr my_ip, netmask, gateway;

    LOG_INF(&amp;quot;Configuring static IP address...&amp;quot;);

    if (net_addr_pton(AF_INET, CONFIG_NET_CONFIG_MY_IPV4_ADDR, &amp;amp;my_ip) &amp;lt; 0) {
        LOG_ERR(&amp;quot;Invalid IP address format&amp;quot;);
        return;
    }
    if (net_addr_pton(AF_INET, &amp;quot;255.255.255.0&amp;quot;, &amp;amp;netmask) &amp;lt; 0) {
        LOG_ERR(&amp;quot;Invalid netmask format&amp;quot;);
        
        return;
    }
    if (net_addr_pton(AF_INET, &amp;quot;192.168.1.1&amp;quot;, &amp;amp;gateway) &amp;lt; 0) {
        LOG_ERR(&amp;quot;Invalid gateway format&amp;quot;);
        return;
    }

    net_if_ipv4_addr_add(iface, &amp;amp;my_ip, NET_ADDR_MANUAL, 0);
    net_if_ipv4_set_netmask(iface, &amp;amp;netmask);
    net_if_ipv4_set_gw(iface, &amp;amp;gateway);

    LOG_INF(&amp;quot;Static IP address configured: %s&amp;quot;, CONFIG_NET_CONFIG_MY_IPV4_ADDR);
    context_connected = true;
}


#define RECEIVER_BUFFER_SIZE 8192  // 최대 8KB 설정
static uint8_t receiverBuffer[RECEIVER_BUFFER_SIZE];

void receive_server_data(int tcpClientSocket) {
    uint16_t receivepacket_size = 0;
    struct pollfd fds = {
        .fd = tcpClientSocket,
        .events = POLLIN,
    };

    int poll_result = poll(&amp;amp;fds, 1, 5000);  // 타임아웃 5초
    if (poll_result &amp;lt; 0) {
        LOG_ERR(&amp;quot;Poll error: %d (%s)&amp;quot;, errno, strerror(errno));
        return;
    }

    if (poll_result &amp;gt; 0 &amp;amp;&amp;amp; (fds.revents &amp;amp; POLLIN)) 
    {
        int receivedBytes = recv(tcpClientSocket, receiverBuffer, sizeof(receiverBuffer), 0);
        // int receivedBytes = recv(tcpClientSocket, receiverBuffer, MIN(RECEIVER_BUFFER_SIZE, 2048), 0);

        if (receivedBytes &amp;gt; 0) 
        {
            LOG_INF(&amp;quot;Received data length: %d&amp;quot;, receivedBytes);
            for (int i = 0; i &amp;lt; receivedBytes; i++) {
                // LOG_INF(&amp;quot;Received data[%d]: %x&amp;quot;, i, receiverBuffer[i]);
            }

            receivepacket_size = ((uint32_t)receiverBuffer[0]        |
                                 ((uint32_t)receiverBuffer[1] &amp;lt;&amp;lt; 8)  |
                                 ((uint32_t)receiverBuffer[2] &amp;lt;&amp;lt; 16) |
                                 ((uint32_t)receiverBuffer[3] &amp;lt;&amp;lt; 24));
            LOG_INF(&amp;quot;---------- My Received Packet Size : %d&amp;quot;, receivepacket_size);

            if(	receiverBuffer[4] == 0x86 &amp;amp;&amp;amp;
				receiverBuffer[5] == 0x00 )
            {    //맥어드레스 등 초기 정보 확인인
                packet_start = true; 
				send_flag = true;

                LOG_INF(&amp;quot;-- Start packet Receive --&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x84 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Amp, Sens, 베터리 등 설정 정보 한번에 받기
                LOG_INF(&amp;quot;pcb setting info.&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x88 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Battery Voltage 정보 받기
                LOG_INF(&amp;quot;Battery info&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x31 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //센서 Data 1개 받기
                LOG_INF(&amp;quot;Sensor Data 1ea receive&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x33 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //저장된 센서 Data를 최근 최대 60개 받기
                LOG_INF(&amp;quot;Sensor Data 60ea receive&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x35 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //데이터가 N개 쌓이면 Stream Data를 자동으로 전송하는 Data Stream Mode 시작
                LOG_INF(&amp;quot;N ea Data recweive Start&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x37 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //데이터가 N개 쌓이면 Stream Data를 자동으로 전송하는 Data Stream Mode 종료
                LOG_INF(&amp;quot;N ea Data recweive Stop&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x42 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Sleep Mode 시작하기
                LOG_INF(&amp;quot;Sleep Mode Start&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x41 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Light Sleep Mode 시작하기
                LOG_INF(&amp;quot;Light Sleep Mode Start&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x01 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Firmware Version 받기
                LOG_INF(&amp;quot;Firmware Version Receive&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x04 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //TCP 통신 서버의 IP 받기
                LOG_INF(&amp;quot;TCO Server IP Receive&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x24 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //TCP 통신 서버의 IP 설정하기
                LOG_INF(&amp;quot;TCP Server IP Setting&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x05 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //TCP 통신 서버의 Port 받기
                LOG_INF(&amp;quot;TCP Server Port receive&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x25 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //TCP 통신 서버의 Port 설정하기
                LOG_INF(&amp;quot;TCP Server Port Setting&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x06 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Client Mode 도중
                LOG_INF(&amp;quot;Client Mode ing?,,&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x07 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //센서 측정 간격 받기
                LOG_INF(&amp;quot;Sensor Speed Receive&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x27 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //센서 측정 간격 설정하기
                flash_save_data(0, receiverBuffer[6]);
                received_tcp_data_flag = true;
                LOG_INF(&amp;quot;Sensor Speed Setting&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x08 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Amplification 받기
                LOG_INF(&amp;quot;Amp Data receive&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x28 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Amplification 설정하기
                flash_save_data(1, receiverBuffer[6]);
                received_tcp_data_flag = true;
                LOG_INF(&amp;quot;Amp Value Setting : %d&amp;quot;, received_tcp_data.amp);
            }
            else if( receiverBuffer[4] == 0x09 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Sensitivity 받기기
                LOG_INF(&amp;quot;Sens Data receive&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x29 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Sensitivity 설정하기
                flash_save_data(2, receiverBuffer[6]);
                received_tcp_data_flag = true;
                LOG_INF(&amp;quot;Sens Value Setting : %d&amp;quot;, received_tcp_data.sens);
            }
            else if( receiverBuffer[4] == 0x0a &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //저항 3 값 받기
                LOG_INF(&amp;quot;Res3 Data receive&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x2a &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //저항3 값 설정하기
                flash_save_data(3, receiverBuffer[6]);
                received_tcp_data_flag = true;
                LOG_INF(&amp;quot;Res3 Value Setting : %d&amp;quot;, received_tcp_data.res3);
            }
            else if( receiverBuffer[4] == 0x0f &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Wake up 값 받기
                LOG_INF(&amp;quot;Wake Up Value receive&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x2f &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Wake up 값 설정하기
                LOG_INF(&amp;quot;Wake up value setting&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x51 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //모터 동작하기
                LOG_INF(&amp;quot;Motor Start&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x91 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Firmware 업데이트 Mode 시작하기기
                LOG_INF(&amp;quot;Firmware Update Mode Start&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x92 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Firmware 파일 업로드드
                LOG_INF(&amp;quot;Firmware file upload&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x93 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Formware 파일 체크섬섬
                LOG_INF(&amp;quot;Firmware file checksum&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x64 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Data Stream Mode의 60개마다 자동으로 전송하는 Data Stream 기기에서 송신(기기 -&amp;gt; 서버) / 스트림 모드 동작시 센서 데이터 보내는 패킷
                LOG_INF(&amp;quot;      1&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x66 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //10초 이상 Wake up value 이상과 이하가 바뀌었을 때 기기에서 송신(기기 -&amp;gt; 서버) / 착좌감지지
                LOG_INF(&amp;quot;         2&amp;quot;);
            }
            else if( receiverBuffer[4] == 0x62 &amp;amp;&amp;amp;
				     receiverBuffer[5] == 0x00 )
            {   //Disconnect될 때 기기에서 송신(기기 -&amp;gt; 서버버)
                LOG_INF(&amp;quot;         3  &amp;quot;);
            }

        } else if (receivedBytes == 0) {
            LOG_INF(&amp;quot;Server closed the connection.&amp;quot;);
        } else {
            LOG_ERR(&amp;quot;Receive error: %d&amp;quot;, errno);
        }
    } else {
        LOG_ERR(&amp;quot;No data received from server within timeout.&amp;quot;);
    }
}


#define MAX_PACKET_SIZE 1000  // MSS 값

void send_sensor_data(int tcpClientSocket) {
    if (!send_flag) return;

	int sentBytes = 0;
    int retry_count = 0;
    const int max_retries = 5; // 최대 5번 %EC%9E%AC시도 후 재연결

    if (send_flag) {
		if(packet_start == true)
		{
            LOG_INF(&amp;quot;normal data send--&amp;quot;);
            packet_start = false;
			sentBytes = send(tcpClientSocket, TCPClientMessage, sizeof(TCPClientMessage), 0);

            if (sentBytes &amp;gt; 0) {
                k_msleep(10);  // 데이터 전송 후 10ms 대기 (TCP 윈도우가 열릴 시간 제공)
            } else if (sentBytes &amp;lt; 0) {
                LOG_ERR(&amp;quot;Send error: %d&amp;quot;, errno);
                return; // 연결 상태를 체크해야 함
            }

			// if (--packet_start &amp;lt;= 0) {
            //     send_flag = false;
			// 	packet_start = 0;
            // }
		}
		else
		{
			send_flag = false;
			
			if (fsr_data_flag == true) {
				fsr_data_flag = false;  // 플래그 초기화

                // ✅ adc_fsr_converted가 NULL이거나 크기가 0이면 오류 처리
                if (!adc_fsr_converted || adc_fsr_converted_size == 0) {
                    LOG_ERR(&amp;quot;ADC data is NULL or empty, cannot send&amp;quot;);
                    return;
                }

				LOG_INF(&amp;quot;Sending ADC sensor data to server...\n&amp;quot;);

                size_t total_size = adc_fsr_converted_size;
                size_t sent = 0;
                LOG_INF(&amp;quot;-----total_size: %d bytes-----&amp;quot;, total_size);

                while (sent &amp;lt; total_size) {
                    size_t chunk_size = MIN(MAX_PACKET_SIZE, total_size - sent);

                    struct pollfd fds;
                    fds.fd = tcpClientSocket;
                    fds.events = POLLOUT;  // 송신 가능 여부 체크
                
                    int ret = poll(&amp;amp;fds, 1, 1000);  // 최대 1초 대기
                    if (ret &amp;gt; 0 &amp;amp;&amp;amp; (fds.revents &amp;amp; POLLOUT)) {
                        sentBytes = send(tcpClientSocket, ((uint8_t*)adc_fsr_converted) + sent, chunk_size, 0);

                        if (sentBytes &amp;gt; 0) {
                            k_msleep(10);  // 데이터 전송 후 10ms 대기 (TCP 윈도우가 열릴 시간 제공)
                            sent += sentBytes;
                            retry_count = 0; // 성공하면 재시도 횟수 초기화
                        } else {
                            LOG_ERR(&amp;quot;Send error: %d&amp;quot;, errno);
                            retry_count++;
                        }
                
                        // if (sentBytes &amp;lt; 0) {
                        //     LOG_ERR(&amp;quot;Send error: %d&amp;quot;, errno);
                        //     break;
                        // }
                        // sent += sentBytes;
                    } else {
                        // k_msleep(500);  // 딜레이 추가
                        LOG_ERR(&amp;quot;Socket not ready for sending, retrying...&amp;quot;);
                        retry_count++;
                    }

                    if (retry_count &amp;gt;= max_retries) {
                        LOG_ERR(&amp;quot;Max send retries reached. Closing socket and reconnecting...&amp;quot;);
                        k_msleep(10000);

                        retry_count = 0;
                        close_socket(&amp;amp;tcpClientSocket);
                        tcpClientSocket = -1;
                        
                        return; // TCP_Client 루프에서 재연결 시도
                    }
                }

                printk(&amp;quot;************************************************************\n&amp;quot;);
                printk(&amp;quot;Total Sent ADC data length: %d bytes\n&amp;quot;, sent);
				//for(uint8_t i = 0; i &amp;lt; 16; i+=4) printk(&amp;quot;%d, %d, %d, %d \n&amp;quot;, adc_fsr_converted[i], adc_fsr_converted[i+1], adc_fsr_converted[i+2], adc_fsr_converted[i+3]);
				printk(&amp;quot;\n&amp;quot;);

                // ✅ 전송이 성공적으로 완료되었을 때만 메모리 해제
                if (sent == total_size) {
                    LOG_INF(&amp;quot;Send ADC data completed. Freeing memory.&amp;quot;);
                    LOG_INF(&amp;quot;Send ADC data length: %d&amp;quot;, sent);
                    k_free(adc_fsr_converted);  // ✅ 여기가 올바른 위치
                    adc_fsr_converted = NULL;   // ✅ 해제 후 NULL로 초기화
                    adc_fsr_converted_size = 0;  // ✅ 크기 초기화
                } else {
                    LOG_ERR(&amp;quot;Partial send error, not freeing memory&amp;quot;);
                }

				if (sentBytes &amp;lt; 0) {
					LOG_ERR(&amp;quot;Send error: %d&amp;quot;, errno);
				} else {
					LOG_INF(&amp;quot;Send ADC data length: %d&amp;quot;, sentBytes);
				}
			}
		}
    }
}


bool monitor_connection_status(int tcpClientSocket) {
    struct pollfd fds = {
        .fd = tcpClientSocket,
        .events = POLLIN | POLLHUP | POLLERR,
    };

    int poll_result = poll(&amp;amp;fds, 1, 100);  // 100ms 대기

    if (poll_result &amp;gt; 0) {
        if (fds.revents &amp;amp; (POLLHUP | POLLERR)) {
            LOG_ERR(&amp;quot;Connection closed by server or socket error.&amp;quot;);
            return false;  // 연결 끊김
        } 
        // else if (fds.revents &amp;amp; POLLERR) {
        //     LOG_ERR(&amp;quot;Socket error detected.&amp;quot;);
        //     return false;  // 소켓 에러
        // }
    } else if (poll_result &amp;lt; 0) {
        LOG_ERR(&amp;quot;Poll error: %d&amp;quot;, errno);
        return false;  // Poll 에러 발생
    }

    return true;  // 연결 유지 중
}


/*! TCP_Client implements the TCP Client task.
* @brief TCP_Client uses a BSD socket estabilish a connection with a defined
* 		TCP server. 
* 		A sample message will be sent to the IP address defined on the 
*		configuration file as Peer address.
* 		This function is used on an independent thread.
*/

// bool send_flag = false;
// bool receive_flag = false;
// int packet_start = 0;
// bool packet_flag = false;
void TCP_Client(void) {
    // int tcpClientSocket;
    struct sockaddr_in serverAddress;
    int retry_count = 0;
    const int max_retries = 5;

    LOG_INF(&amp;quot;Waiting for network to be ready...&amp;quot;);
    while (context.connected != true) {
		k_msleep( TCP_CLIENT_SLEEP_TIME_MS );
    }

    LOG_INF(&amp;quot;Configuring server address...&amp;quot;);       // 서버 주소 설정
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(TCP_CLIENT_PORT);
    inet_pton(AF_INET, CONFIG_NET_CONFIG_PEER_IPV4_ADDR, &amp;amp;serverAddress.sin_addr);

    while (1) {
        retry_count = 0;  // ✅ 5회 재시도 후 1분 대기 후 다시 5회 재시도할 때 초기화

        while (retry_count &amp;lt; max_retries) {
            LOG_INF(&amp;quot;Attempting to create socket...&amp;quot;);
            tcpClientSocket = socket(serverAddress.sin_family, SOCK_STREAM, IPPROTO_TCP);

            if (tcpClientSocket &amp;lt; 0) {
                LOG_ERR(&amp;quot;Socket creation failed: %d&amp;quot;, errno);
                k_msleep(5000);
                retry_count++;
                continue;
            }

            LOG_INF(&amp;quot;Attempting to connect to server...&amp;quot;);
            if (connect(tcpClientSocket, (struct sockaddr *)&amp;amp;serverAddress, sizeof(serverAddress)) &amp;lt; 0) {
                LOG_ERR(&amp;quot;Connection failed: %d&amp;quot;, errno);
                close_socket(&amp;amp;tcpClientSocket);
                k_msleep(5000);
                retry_count++;
                continue;
            }

            LOG_INF(&amp;quot;Connected to server successfully.&amp;quot;);
            retry_count = 0;  // ✅ 연결 성공 시 카운터 초기화

            
            // 소켓 옵션 설정
            // 1. SO_KEEPALIVE 설정
            int optval = 1;
            setsockopt(tcpClientSocket, SOL_SOCKET, SO_KEEPALIVE, &amp;amp;optval, sizeof(optval));

            // 소켓 재사용 옵션 추가
            setsockopt(tcpClientSocket, SOL_SOCKET, SO_REUSEADDR, &amp;amp;optval, sizeof(optval));

            struct timeval timeout = {.tv_sec = 5, .tv_usec = 0};
            setsockopt(tcpClientSocket, SOL_SOCKET, SO_RCVTIMEO, &amp;amp;timeout, sizeof(timeout));
            setsockopt(tcpClientSocket, SOL_SOCKET, SO_SNDTIMEO, &amp;amp;timeout, sizeof(timeout));

            // 송수신 병렬 처리 루프
            while (1) 
            {
                if(fsr_data_flag == true) send_flag = true;
                
                receive_server_data(tcpClientSocket);
                send_sensor_data(tcpClientSocket);

                // 연결 상태 확인
                if (!monitor_connection_status(tcpClientSocket)) {
                    LOG_ERR(&amp;quot;Connection lost. Attempting to reconnect...&amp;quot;);
                    packet_start = false;
                    close_socket(&amp;amp;tcpClientSocket);
                    k_msleep(5000);  // 재연결 전 5초 대기
                    break;  // 연결 재시도 루프로 이동
                }
                k_msleep(100);
            }
        }
        LOG_ERR(&amp;quot;Max connection attempts (5) reached. Waiting 1 minute before retrying...&amp;quot;);
        k_msleep(60000);  // ⏳ 1분 대기 후 다시 재연결 시도
    }
}


void Task_TCP_Client_Delete( void ) {
	printk(&amp;quot;Task_TCP_Client_Delete\n&amp;quot;);
	
    close_socket(&amp;amp;tcpClientSocket);
	k_thread_abort(&amp;amp;tcpClientThread);
}

/*! Task_TCP_Client_Init initializes the task TCP Client
*
* @brief TCP Client initialization
*/
void Task_TCP_Client_Init( void ){
	printk(&amp;quot;Task_TCP_Client_Init\n&amp;quot;);
	
    // configure_static_ip();
	update_sampling_interval_from_server(500);
	
	k_thread_create	(														\
					&amp;amp;tcpClientThread,										\
					TCP_CLIENT_STACK,										\
					TCP_CLIENT_STACK_SIZE,									\
					(k_thread_entry_t)TCP_Client,							\
					NULL,													\
					NULL,													\
					NULL,													\
					TCP_CLIENT_PRIORITY,									\
					0,														\
					K_NO_WAIT);	

	 k_thread_name_set(&amp;amp;tcpClientThread, &amp;quot;tcpClient&amp;quot;);
	 k_thread_start(&amp;amp;tcpClientThread);


};

&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;nrf53_support.c&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#include &amp;lt;soc.h&amp;gt;
#include &amp;lt;zephyr/device.h&amp;gt;
#include &amp;lt;hal/nrf_reset.h&amp;gt;
#if defined(CONFIG_BT_CTLR_DEBUG_PINS_CPUAPP)
#include &amp;lt;../subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/debug.h&amp;gt;
#else
#define DEBUG_SETUP()
#endif /* defined(CONFIG_BT_CTLR_DEBUG_PINS_CPUAPP) */
#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
#include &amp;lt;zephyr/logging/log.h&amp;gt;
LOG_MODULE_REGISTER(bt_hci_nrf53_support);
int bt_hci_transport_teardown(const struct device *dev)
{
	ARG_UNUSED(dev);
    /* Put core into reset */
	NRF_RESET-&amp;gt;NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Hold;
	LOG_DBG(&amp;quot;Network MCU reseted.&amp;quot;);
    /* Put the Network MCU in Forced-OFF mode. */
	nrf_reset_network_force_off(NRF_RESET, true);
	LOG_DBG(&amp;quot;Network MCU placed in Forced-OFF mode&amp;quot;);

	return 0;
}
int bt_hci_transport_setup(const struct device *dev)
{
	ARG_UNUSED(dev);
#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) || defined(CONFIG_BUILD_WITH_TFM)
	/* Route Bluetooth Controller Debug Pins */
	DEBUG_SETUP();
#endif /* !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) || defined(CONFIG_BUILD_WITH_TFM) */
#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
	/* Retain nRF5340 Network MCU in Secure domain (bus
	 * accesses by Network MCU will have Secure attribute set).
	 */
	NRF_SPU-&amp;gt;EXTDOMAIN[0].PERM = 1 &amp;lt;&amp;lt; 4;
#endif /* !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) */

	NRF_RESET-&amp;gt;NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release;
	/* Release the Network MCU, &amp;#39;Release force off signal&amp;#39; */
	nrf_reset_network_force_off(NRF_RESET, false);

	return 0;
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Problems related to nrf5340 brighton/off</title><link>https://devzone.nordicsemi.com/thread/527378?ContentTypeID=1</link><pubDate>Fri, 14 Mar 2025 13:06:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:03ab9b97-2453-4915-ad8c-9405602df65f</guid><dc:creator>Maria Gilje</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
[quote user=""]We are testing nrf5340 - nrf7002 using the example of blpovisioning.[/quote]
&lt;p&gt;Do you have a link to the example source code or documentation? &lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Maria&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>