-
Notifications
You must be signed in to change notification settings - Fork 222
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
432 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
/********************************************************************* | ||
PicoTCP. Copyright (c) 2012-2015 Altran Intelligent Systems. Some rights reserved. | ||
See LICENSE and COPYING for usage. | ||
Authors: Frederik Van Slycken | ||
*********************************************************************/ | ||
#include "pico_protocol.h" | ||
#include "pico_hotplug_detection.h" | ||
#include "pico_tree.h" | ||
#include "pico_device.h" | ||
|
||
struct pico_hotplug_device{ | ||
struct pico_device *dev; | ||
int prev_state; | ||
struct pico_tree callbacks; | ||
}; | ||
|
||
uint32_t timer_id = 0; | ||
|
||
static int pico_hotplug_dev_cmp(void *ka, void *kb) | ||
{ | ||
struct pico_hotplug_device *a = ka, *b = kb; | ||
if (a->dev->hash < b->dev->hash) | ||
return -1; | ||
|
||
if (a->dev->hash > b->dev->hash) | ||
return 1; | ||
|
||
return 0; | ||
} | ||
|
||
static int callback_compare(void *ka, void *kb) | ||
{ | ||
if (ka < kb) | ||
return -1; | ||
if (ka > kb) | ||
return 1; | ||
return 0; | ||
} | ||
|
||
PICO_TREE_DECLARE(Hotplug_device_tree, pico_hotplug_dev_cmp); | ||
|
||
static void timer_cb(__attribute__((unused)) pico_time t, __attribute__((unused)) void* v) | ||
{ | ||
struct pico_tree_node *node = NULL, *safe = NULL, *cb_node = NULL, *cb_safe = NULL; | ||
int new_state, event; | ||
struct pico_hotplug_device *hpdev = NULL; | ||
void (*cb)(struct pico_device *dev, int event); | ||
|
||
//we don't know if one of the callbacks might deregister, so be safe | ||
pico_tree_foreach_safe(node, &Hotplug_device_tree, safe) | ||
{ | ||
hpdev = node->keyValue; | ||
new_state = hpdev->dev->link_state(hpdev->dev); | ||
if (new_state != hpdev->prev_state) | ||
{ | ||
if (new_state == 1){ | ||
event = PICO_HOTPLUG_EVENT_UP; | ||
} else { | ||
event = PICO_HOTPLUG_EVENT_DOWN; | ||
} | ||
//we don't know if one of the callbacks might deregister, so be safe | ||
pico_tree_foreach_safe(cb_node, &(hpdev->callbacks), cb_safe) | ||
{ | ||
cb = cb_node->keyValue; | ||
cb(hpdev->dev, event); | ||
} | ||
hpdev->prev_state = new_state; | ||
} | ||
} | ||
|
||
timer_id = pico_timer_add(PICO_HOTPLUG_INTERVAL, &timer_cb, NULL); | ||
} | ||
|
||
|
||
int pico_hotplug_register(struct pico_device *dev, void (*cb)(struct pico_device *dev, int event)) | ||
{ | ||
struct pico_hotplug_device *hotplug_dev; | ||
struct pico_hotplug_device search = {.dev = dev}; | ||
|
||
if (dev->link_state == NULL){ | ||
pico_err = PICO_ERR_EPROTONOSUPPORT; | ||
return -1; | ||
} | ||
|
||
hotplug_dev = (struct pico_hotplug_device*)pico_tree_findKey(&Hotplug_device_tree, &search); | ||
if (! hotplug_dev ) | ||
{ | ||
hotplug_dev = PICO_ZALLOC(sizeof(struct pico_hotplug_device)); | ||
if (!hotplug_dev) | ||
{ | ||
pico_err = PICO_ERR_ENOMEM; | ||
return -1; | ||
} | ||
hotplug_dev->dev = dev; | ||
hotplug_dev->prev_state = dev->link_state(hotplug_dev->dev); | ||
hotplug_dev->callbacks.root = &LEAF; | ||
hotplug_dev->callbacks.compare = &callback_compare; | ||
pico_tree_insert(&Hotplug_device_tree, hotplug_dev); | ||
} | ||
pico_tree_insert(&(hotplug_dev->callbacks), cb); | ||
|
||
if (timer_id == 0) | ||
{ | ||
timer_id = pico_timer_add(PICO_HOTPLUG_INTERVAL, &timer_cb, NULL); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int pico_hotplug_deregister(struct pico_device *dev, void (*cb)(struct pico_device *dev, int event)) | ||
{ | ||
struct pico_hotplug_device* hotplug_dev; | ||
struct pico_hotplug_device search = {.dev = dev}; | ||
|
||
hotplug_dev = (struct pico_hotplug_device*)pico_tree_findKey(&Hotplug_device_tree, &search); | ||
if (!hotplug_dev) | ||
//wasn't registered | ||
return 0; | ||
pico_tree_delete(&hotplug_dev->callbacks, cb); | ||
if (pico_tree_empty(&hotplug_dev->callbacks)) | ||
{ | ||
pico_tree_delete(&Hotplug_device_tree, hotplug_dev); | ||
PICO_FREE(hotplug_dev); | ||
} | ||
|
||
if (pico_tree_empty(&Hotplug_device_tree) && timer_id != 0) | ||
{ | ||
pico_timer_cancel(timer_id); | ||
timer_id = 0; | ||
} | ||
return 0; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/********************************************************************* | ||
PicoTCP. Copyright (c) 2012-2015 Altran Intelligent Systems. Some rights reserved. | ||
See LICENSE and COPYING for usage. | ||
Authors: Frederik Van Slycken | ||
*********************************************************************/ | ||
#ifndef INCLUDE_PICO_SUPPORT_HOTPLUG | ||
#define INCLUDE_PICO_SUPPORT_HOTPLUG | ||
#include "pico_stack.h" | ||
|
||
#define PICO_HOTPLUG_EVENT_UP 1 /* link went up */ | ||
#define PICO_HOTPLUG_EVENT_DOWN 2 /* link went down */ | ||
|
||
#define PICO_HOTPLUG_INTERVAL 100 | ||
|
||
int pico_hotplug_register(struct pico_device *dev, void (*cb)(struct pico_device *dev, int event)); | ||
int pico_hotplug_deregister(struct pico_device *dev, void (*cb)(struct pico_device *dev, int event)); | ||
|
||
#endif /* _INCLUDE_PICO_SUPPORT_HOTPLUG */ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
OPTIONS+=-DPICO_SUPPORT_SLAACV4 | ||
MOD_OBJ+=$(LIBBASE)modules/pico_slaacv4.o | ||
MOD_OBJ+=$(LIBBASE)modules/pico_slaacv4.o $(LIBBASE)modules/pico_hotplug_detection.o |
Oops, something went wrong.