diff --git a/pkg/semtech-loramac/contrib/semtech_loramac.c b/pkg/semtech-loramac/contrib/semtech_loramac.c index 97f9bf559d..d0ab259b10 100644 --- a/pkg/semtech-loramac/contrib/semtech_loramac.c +++ b/pkg/semtech-loramac/contrib/semtech_loramac.c @@ -190,7 +190,7 @@ static inline void _set_uplink_counter(semtech_loramac_t *mac, uint8_t *counter) (uint32_t)counter[2] << 8 | counter[3]); - DEBUG("[semtech-loramac] uplink counter: %" PRIu32 " \n", counter4); + DEBUG("[semtech-loramac] reading uplink counter: %" PRIu32 " \n", counter4); mutex_lock(&mac->lock); MibRequestConfirm_t mibReq; @@ -200,6 +200,18 @@ static inline void _set_uplink_counter(semtech_loramac_t *mac, uint8_t *counter) mutex_unlock(&mac->lock); } +static inline void _set_join_state(semtech_loramac_t *mac, bool joined) +{ + DEBUG("[semtech-loramac] set join state ? %d\n", joined); + + mutex_lock(&mac->lock); + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_NETWORK_JOINED; + mibReq.Param.IsNetworkJoined = joined; + LoRaMacMibSetRequestConfirm(&mibReq); + mutex_unlock(&mac->lock); +} + static inline void _read_loramac_config(semtech_loramac_t *mac) { DEBUG("[semtech-loramac] reading configuration from EEPROM\n"); @@ -214,21 +226,33 @@ static inline void _read_loramac_config(semtech_loramac_t *mac) return; } + uint8_t tmp_buf[LORAMAC_APPSKEY_LEN] = { 0 }; + /* LoRaWAN EUIs, Keys and device address */ pos += eeprom_read(pos, mac->deveui, LORAMAC_DEVEUI_LEN); pos += eeprom_read(pos, mac->appeui, LORAMAC_APPEUI_LEN); pos += eeprom_read(pos, mac->appkey, LORAMAC_APPKEY_LEN); - pos += eeprom_read(pos, mac->appskey, LORAMAC_APPSKEY_LEN); - pos += eeprom_read(pos, mac->nwkskey, LORAMAC_NWKSKEY_LEN); - pos += eeprom_read(pos, mac->devaddr, LORAMAC_DEVADDR_LEN); + pos += eeprom_read(pos, tmp_buf, LORAMAC_APPSKEY_LEN); + semtech_loramac_set_appskey(mac, tmp_buf); + pos += eeprom_read(pos, tmp_buf, LORAMAC_NWKSKEY_LEN); + semtech_loramac_set_nwkskey(mac, tmp_buf); - /* uplink counter, mainly used for ABP activation */ + /* Read and set device address */ + uint8_t devaddr[LORAMAC_DEVADDR_LEN]; + pos += eeprom_read(pos, devaddr, LORAMAC_DEVADDR_LEN); + + semtech_loramac_set_devaddr(mac, devaddr); + + /* uplink counter */ uint8_t counter[4] = { 0 }; pos += eeprom_read(pos, counter, 4); _set_uplink_counter(mac, counter); + + uint8_t joined = eeprom_read_byte(pos); + _set_join_state(mac, (bool)joined); } -static inline void _save_uplink_counter(semtech_loramac_t *mac) +static inline size_t _save_uplink_counter(semtech_loramac_t *mac) { size_t pos = SEMTECH_LORAMAC_EEPROM_START + SEMTECH_LORAMAC_EEPROM_MAGIC_LEN + @@ -236,17 +260,19 @@ static inline void _save_uplink_counter(semtech_loramac_t *mac) LORAMAC_APPKEY_LEN + LORAMAC_APPSKEY_LEN + LORAMAC_NWKSKEY_LEN + LORAMAC_DEVADDR_LEN; - uint8_t counter[4]; + uint8_t counter[LORAMAC_DEVADDR_LEN]; mutex_lock(&mac->lock); MibRequestConfirm_t mibReq; mibReq.Type = MIB_UPLINK_COUNTER; LoRaMacMibGetRequestConfirm(&mibReq); + DEBUG("[semtech-loramac] saving uplink counter: %" PRIu32 " \n", + mibReq.Param.UpLinkCounter); counter[0] = (uint8_t)(mibReq.Param.UpLinkCounter >> 24); counter[1] = (uint8_t)(mibReq.Param.UpLinkCounter >> 16); counter[2] = (uint8_t)(mibReq.Param.UpLinkCounter >> 8); counter[3] = (uint8_t)(mibReq.Param.UpLinkCounter); mutex_unlock(&mac->lock); - pos += eeprom_write(pos, counter, 4); + return eeprom_write(pos, counter, LORAMAC_DEVADDR_LEN); } void semtech_loramac_save_config(semtech_loramac_t *mac) @@ -258,15 +284,27 @@ void semtech_loramac_save_config(semtech_loramac_t *mac) pos += eeprom_write(pos, magic, SEMTECH_LORAMAC_EEPROM_MAGIC_LEN); /* Store EUIs, Keys and device address */ + uint8_t tmp_buf[LORAMAC_APPSKEY_LEN] = { 0 }; + pos += eeprom_write(pos, mac->deveui, LORAMAC_DEVEUI_LEN); pos += eeprom_write(pos, mac->appeui, LORAMAC_APPEUI_LEN); pos += eeprom_write(pos, mac->appkey, LORAMAC_APPKEY_LEN); - pos += eeprom_write(pos, mac->appskey, LORAMAC_APPSKEY_LEN); - pos += eeprom_write(pos, mac->nwkskey, LORAMAC_NWKSKEY_LEN); - pos += eeprom_write(pos, mac->devaddr, LORAMAC_DEVADDR_LEN); + + semtech_loramac_get_appskey(mac, tmp_buf); + pos += eeprom_write(pos, tmp_buf, LORAMAC_APPSKEY_LEN); + semtech_loramac_get_nwkskey(mac, tmp_buf); + pos += eeprom_write(pos, tmp_buf, LORAMAC_NWKSKEY_LEN); + + uint8_t devaddr[LORAMAC_DEVADDR_LEN]; + semtech_loramac_get_devaddr(mac, devaddr); + pos += eeprom_write(pos, devaddr, LORAMAC_DEVADDR_LEN); /* save uplink counter, mainly used for ABP activation */ - _save_uplink_counter(mac); + pos += _save_uplink_counter(mac); + + /* save join state */ + uint8_t joined = (uint8_t)semtech_loramac_is_mac_joined(mac); + eeprom_write_byte(pos, joined); } void semtech_loramac_erase_config(void) @@ -283,12 +321,13 @@ void semtech_loramac_erase_config(void) MibRequestConfirm_t mibReq; size_t uplink_counter_len = sizeof(mibReq.Param.UpLinkCounter); + size_t joined_state_len = sizeof(mibReq.Param.IsNetworkJoined); size_t end = (pos + SEMTECH_LORAMAC_EEPROM_MAGIC_LEN + LORAMAC_DEVEUI_LEN + LORAMAC_APPEUI_LEN + LORAMAC_APPKEY_LEN + LORAMAC_APPSKEY_LEN + LORAMAC_NWKSKEY_LEN + LORAMAC_DEVADDR_LEN + - uplink_counter_len); + uplink_counter_len + joined_state_len); for (size_t p = pos; p < end; p++) { eeprom_write_byte(p, 0); } @@ -391,29 +430,16 @@ static void _join_abp(semtech_loramac_t *mac) mutex_lock(&mac->lock); MibRequestConfirm_t mibReq; - mibReq.Type = MIB_NETWORK_JOINED; - mibReq.Param.IsNetworkJoined = false; - LoRaMacMibSetRequestConfirm(&mibReq); - - mibReq.Type = MIB_DEV_ADDR; - mibReq.Param.DevAddr = ((uint32_t)mac->devaddr[0] << 24 | - (uint32_t)mac->devaddr[1] << 16 | - (uint32_t)mac->devaddr[2] << 8 | - (uint32_t)mac->devaddr[3]); - LoRaMacMibSetRequestConfirm(&mibReq); - - mibReq.Type = MIB_NWK_SKEY; - mibReq.Param.NwkSKey = mac->nwkskey; - LoRaMacMibSetRequestConfirm(&mibReq); - - mibReq.Type = MIB_APP_SKEY; - mibReq.Param.AppSKey = mac->appskey; - LoRaMacMibSetRequestConfirm(&mibReq); - mibReq.Type = MIB_NETWORK_JOINED; mibReq.Param.IsNetworkJoined = true; LoRaMacMibSetRequestConfirm(&mibReq); mutex_unlock(&mac->lock); + + /* ABP join procedure always works */ + msg_t msg; + msg.type = MSG_TYPE_LORAMAC_JOIN_STATUS; + msg.content.value = SEMTECH_LORAMAC_JOIN_SUCCEEDED; + msg_send(&msg, semtech_loramac_pid); } static void _join(semtech_loramac_t *mac, void *arg) @@ -793,7 +819,7 @@ int semtech_loramac_init(semtech_loramac_t *mac) return 0; } -static bool _is_mac_joined(semtech_loramac_t *mac) +bool semtech_loramac_is_mac_joined(semtech_loramac_t *mac) { mutex_lock(&mac->lock); MibRequestConfirm_t mibReq; @@ -809,7 +835,7 @@ uint8_t semtech_loramac_join(semtech_loramac_t *mac, uint8_t type) { DEBUG("[semtech-loramac] Starting join procedure: %d\n", type); - if (_is_mac_joined(mac)) { + if (semtech_loramac_is_mac_joined(mac)) { DEBUG("[semtech-loramac] network is already joined\n"); return SEMTECH_LORAMAC_ALREADY_JOINED; } @@ -818,15 +844,11 @@ uint8_t semtech_loramac_join(semtech_loramac_t *mac, uint8_t type) _semtech_loramac_call(_join, &type); - if (type == LORAMAC_JOIN_OTAA) { - /* Wait until the MAC replies about OTAA join procedure */ - msg_t msg; - msg_receive(&msg); - return (uint8_t)msg.content.value; - } + /* Wait until the MAC replies about join procedure */ + msg_t msg; + msg_receive(&msg); - /* ABP join procedure always works */ - return SEMTECH_LORAMAC_JOIN_SUCCEEDED; + return (uint8_t)msg.content.value; } #ifdef MODULE_SEMTECH_LORAMAC_RX @@ -842,7 +864,7 @@ void semtech_loramac_request_link_check(semtech_loramac_t *mac) uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len) { - if (!_is_mac_joined(mac)) { + if (!semtech_loramac_is_mac_joined(mac)) { DEBUG("[semtech-loramac] network is not joined\n"); return SEMTECH_LORAMAC_NOT_JOINED; } diff --git a/pkg/semtech-loramac/contrib/semtech_loramac_getset.c b/pkg/semtech-loramac/contrib/semtech_loramac_getset.c index 72d9e8d671..5869b947ce 100644 --- a/pkg/semtech-loramac/contrib/semtech_loramac_getset.c +++ b/pkg/semtech-loramac/contrib/semtech_loramac_getset.c @@ -61,32 +61,69 @@ void semtech_loramac_get_appkey(const semtech_loramac_t *mac, uint8_t *key) void semtech_loramac_set_appskey(semtech_loramac_t *mac, const uint8_t *skey) { - memcpy(mac->appskey, skey, LORAMAC_APPSKEY_LEN); + mutex_lock(&mac->lock); + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_APP_SKEY; + memcpy(mibReq.Param.AppSKey, skey, LORAMAC_APPSKEY_LEN); + LoRaMacMibSetRequestConfirm(&mibReq); + mutex_unlock(&mac->lock); } -void semtech_loramac_get_appskey(const semtech_loramac_t *mac, uint8_t *skey) +void semtech_loramac_get_appskey(semtech_loramac_t *mac, uint8_t *skey) { - memcpy(skey, mac->appskey, LORAMAC_APPSKEY_LEN); + mutex_lock(&mac->lock); + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_APP_SKEY; + LoRaMacMibGetRequestConfirm(&mibReq); + memcpy(skey, mibReq.Param.AppSKey, LORAMAC_APPSKEY_LEN); + mutex_unlock(&mac->lock); } void semtech_loramac_set_nwkskey(semtech_loramac_t *mac, const uint8_t *skey) { - memcpy(mac->nwkskey, skey, LORAMAC_NWKSKEY_LEN); + mutex_lock(&mac->lock); + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_NWK_SKEY; + memcpy(mibReq.Param.NwkSKey, skey, LORAMAC_NWKSKEY_LEN); + LoRaMacMibSetRequestConfirm(&mibReq); + mutex_unlock(&mac->lock); } -void semtech_loramac_get_nwkskey(const semtech_loramac_t *mac, uint8_t *skey) +void semtech_loramac_get_nwkskey(semtech_loramac_t *mac, uint8_t *skey) { - memcpy(skey, mac->nwkskey, LORAMAC_NWKSKEY_LEN); + mutex_lock(&mac->lock); + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_NWK_SKEY; + LoRaMacMibGetRequestConfirm(&mibReq); + memcpy(skey, mibReq.Param.NwkSKey, LORAMAC_NWKSKEY_LEN); + mutex_unlock(&mac->lock); } void semtech_loramac_set_devaddr(semtech_loramac_t *mac, const uint8_t *addr) { - memcpy(mac->devaddr, addr, LORAMAC_DEVADDR_LEN); + mutex_lock(&mac->lock); + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_DEV_ADDR; + mibReq.Param.DevAddr = ((uint32_t)addr[0] << 24 | + (uint32_t)addr[1] << 16 | + (uint32_t)addr[2] << 8 | + (uint32_t)addr[3]); + LoRaMacMibSetRequestConfirm(&mibReq); + mutex_unlock(&mac->lock); } -void semtech_loramac_get_devaddr(const semtech_loramac_t *mac, uint8_t *addr) +void semtech_loramac_get_devaddr(semtech_loramac_t *mac, uint8_t *addr) { - memcpy(addr, mac->devaddr, LORAMAC_DEVADDR_LEN); + mutex_lock(&mac->lock); + DEBUG("[semtech-loramac] get device address\n"); + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_DEV_ADDR; + LoRaMacMibGetRequestConfirm(&mibReq); + addr[0] = (uint8_t)(mibReq.Param.DevAddr >> 24); + addr[1] = (uint8_t)(mibReq.Param.DevAddr >> 16); + addr[2] = (uint8_t)(mibReq.Param.DevAddr >> 8); + addr[3] = (uint8_t)(mibReq.Param.DevAddr); + mutex_unlock(&mac->lock); } void semtech_loramac_set_class(semtech_loramac_t *mac, loramac_class_t cls) diff --git a/pkg/semtech-loramac/include/semtech_loramac.h b/pkg/semtech-loramac/include/semtech_loramac.h index 976ecc3660..16e60a4688 100644 --- a/pkg/semtech-loramac/include/semtech_loramac.h +++ b/pkg/semtech-loramac/include/semtech_loramac.h @@ -123,9 +123,6 @@ typedef struct { uint8_t deveui[LORAMAC_DEVEUI_LEN]; /**< device EUI */ uint8_t appeui[LORAMAC_APPEUI_LEN]; /**< application EUI */ uint8_t appkey[LORAMAC_APPKEY_LEN]; /**< application key */ - uint8_t appskey[LORAMAC_APPSKEY_LEN]; /**< application session key */ - uint8_t nwkskey[LORAMAC_NWKSKEY_LEN]; /**< network session key */ - uint8_t devaddr[LORAMAC_DEVADDR_LEN]; /**< device address */ #if defined(MODULE_SEMTECH_LORAMAC_RX) || DOXYGEN semtech_loramac_rx_data_t rx_data; /**< struct handling the RX data */ semtech_loramac_link_check_info_t link_chk; /**< link check information */ @@ -205,6 +202,15 @@ uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len) uint8_t semtech_loramac_recv(semtech_loramac_t *mac); #endif +/** + * @brief Check if network is already joined + * + * @param[in] mac Pointer to the mac + * + * @return true when network is joined, false otherwise + */ +bool semtech_loramac_is_mac_joined(semtech_loramac_t *mac); + #if defined(MODULE_SEMTECH_LORAMAC_RX) || DOXYGEN /** * @brief Requests a LoRaWAN link check @@ -279,7 +285,7 @@ void semtech_loramac_set_appskey(semtech_loramac_t *mac, const uint8_t *skey); * @param[in] mac Pointer to the mac * @param[in] skey The application session key */ -void semtech_loramac_get_appskey(const semtech_loramac_t *mac, uint8_t *skey); +void semtech_loramac_get_appskey(semtech_loramac_t *mac, uint8_t *skey); /** * @brief Sets the network session key @@ -295,7 +301,7 @@ void semtech_loramac_set_nwkskey(semtech_loramac_t *mac, const uint8_t *skey); * @param[in] mac Pointer to the mac * @param[in] skey The network session key */ -void semtech_loramac_get_nwkskey(const semtech_loramac_t *mac, uint8_t *skey); +void semtech_loramac_get_nwkskey(semtech_loramac_t *mac, uint8_t *skey); /** * @brief Sets the device address @@ -311,7 +317,7 @@ void semtech_loramac_set_devaddr(semtech_loramac_t *mac, const uint8_t *addr); * @param[in] mac Pointer to the mac * @param[in] addr The device address */ -void semtech_loramac_get_devaddr(const semtech_loramac_t *mac, uint8_t *addr); +void semtech_loramac_get_devaddr(semtech_loramac_t *mac, uint8_t *addr); /** * @brief Sets the device class