int32_t ifIndex; /**< network interface index */
} CAIfItem_t;
+/**
+ * Hold the port number assigned from application.
+ * It will be used when creating a socket.
+ */
+typedef struct
+{
+ struct udpports
+ {
+ uint16_t u6; /**< unicast IPv6 socket port */
+ uint16_t u6s; /**< unicast IPv6 socket secure port */
+ uint16_t u4; /**< unicast IPv4 socket port */
+ uint16_t u4s; /**< unicast IPv4 socket secure port */
+ } udp;
+#ifdef TCP_ADAPTER
+ struct tcpports
+ {
+ uint16_t u4; /**< unicast IPv4 socket port */
+ uint16_t u6; /**< unicast IPv6 socket port */
+ } tcp;
+#endif
+} CAPorts_t;
+
typedef struct
{
CATransportFlags_t clientFlags; /**< flag for client */
bool client; /**< client mode */
bool server; /**< server mode */
+ CAPorts_t ports;
+
struct sockets
{
void *threadpool; /**< threadpool between Initialize and Start */
*/
CAResult_t CAUnsetAutoConnectionDeviceInfo(const char* address);
+/**
+ * Set the port number to assign .
+ * @param[in] adapter Transport adapter information.
+ * @param[in] flag Transport flag information.
+ * @param[in] port The port number to use.
+ *
+ * @return ::CA_STATUS_OK or ::CA_STATUS_FAILED.
+ */
+CAResult_t CASetPortNumberToAssign(CATransportAdapter_t adapter,
+ CATransportFlags_t flag, uint16_t port);
+
+/**
+ * Get the assigned port number currently.
+ * @param[in] adapter Transport adapter information.
+ * @param[in] flag Transport flag information.
+ *
+ * @return assigned port number information.
+ */
+uint16_t CAGetAssignedPortNumber(CATransportAdapter_t adapter, CATransportFlags_t flag);
+
#ifdef __ANDROID__
/**
* initialize util client for android
{
return coap_tcp_16bit;
}
- else if (size < ULONG_MAX + COAP_TCP_LENGTH_FIELD_32_BIT)
+ else if (size - COAP_TCP_LENGTH_FIELD_32_BIT < ULONG_MAX)
{
return coap_tcp_32bit;
}
OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
}
- if (GATT_ERROR == status)
+ if (CALECheckConnectionStateValue(status))
{
- // when we get GATT ERROR(0x85), gatt connection can be called again.
- OIC_LOG(INFO, TAG, "retry gatt connect");
-
- jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
- if (!leAddress)
- {
- OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
- goto error_exit;
- }
-
- jobject btObject = CALEGetRemoteDevice(env, leAddress);
- if (!btObject)
- {
- OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
- goto error_exit;
- }
-
- jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
- if (!newGatt)
- {
- OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
- goto error_exit;
- }
-
- return;
+ // this state is unexpected reason to disconnect
+ // if the reason is suitable, connection logic of the device will be destroyed.
+ OIC_LOG(INFO, TAG, "connection logic destroy");
+ goto error_exit;
}
else
{
- if (CALECheckConnectionStateValue(status))
- {
- // this state is unexpected reason to disconnect
- // if the reason is suitable, connection logic of the device will be destroyed.
- OIC_LOG(INFO, TAG, "connection logic destroy");
- goto error_exit;
- }
- else
- {
- // other reason except for gatt_success is expected to running
- // background connection in BT platform.
- OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
- CALEClientUpdateSendCnt(env);
- return;
- }
+ // other reason except for gatt_success is expected to running
+ // background connection in BT platform.
+ OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
+ CALEClientUpdateSendCnt(env);
+ return;
}
if (g_sendBuffer)
/**
* Callback to notify any error in LE adapter.
*/
-static CABLEErrorHandleCallback g_serverErrorCallback;
+static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
/**
* To keep the state of GATT server if started or not.
// Kill g main loops and kill threads
g_main_loop_quit(g_eventLoop);
}
+ g_eventLoop = NULL;
}
else
{
return CA_STATUS_FAILED;
}
- bt_gatt_server_h server;
-
- ret = bt_gatt_server_create(&server);
- if (0 != ret)
- {
- OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
- CALEGetErrorMsg(ret));
- return CA_STATUS_FAILED;
- }
-
- if (NULL != g_gattServer)
+ if (!g_gattServer)
{
- OICFree(g_gattServer);
- g_gattServer = NULL;
+ OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
+ ret = bt_gatt_server_create(&g_gattServer);
+ if (0 != ret)
+ {
+ OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
+ CALEGetErrorMsg(ret));
+ return CA_STATUS_FAILED;
+ }
}
- g_gattServer = server;
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
CALEGetErrorMsg(ret));
return CA_STATUS_FAILED;
}
+ g_gattServer = NULL;
ret = bt_gatt_server_deinitialize();
if (0 != ret)
OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
- bt_gatt_h service = NULL;
bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
- int ret = bt_gatt_service_create(serviceUUID, type, &service);
+ ca_mutex_lock(g_leServiceMutex);
+ int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
if (0 != ret)
{
+ ca_mutex_unlock(g_leServiceMutex);
OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
- CALEGetErrorMsg(ret));
+ CALEGetErrorMsg(ret));
return CA_STATUS_FAILED;
}
+ ca_mutex_unlock(g_leServiceMutex);
- if (NULL != service)
+ if (g_gattSvcPath)
{
- OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)service);
-
- ca_mutex_lock(g_leServiceMutex);
-
- if (NULL != g_gattSvcPath)
- {
- OICFree(g_gattSvcPath);
- g_gattSvcPath = NULL;
- }
- g_gattSvcPath = service;
-
- ca_mutex_unlock(g_leServiceMutex);
+ OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
}
OIC_LOG(DEBUG, TAG, "OUT");
int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
int properties;
- if(read)
+ if (read)
{
properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
}
properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
}
- bt_gatt_h charPath;
+ bt_gatt_h charPath = NULL;
int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
charValueLen, &charPath);
&descriptor);
if (0 != ret)
{
+ ca_mutex_unlock(g_leCharacteristicMutex);
OIC_LOG_V(ERROR, TAG,
"bt_gatt_descriptor_create failed with ret[%s]",
CALEGetErrorMsg(ret));
ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
if (0 != ret)
{
+ ca_mutex_unlock(g_leCharacteristicMutex);
OIC_LOG_V(ERROR, TAG,
"bt_gatt_characteristic_add_descriptor failed with ret[%s]",
CALEGetErrorMsg(ret));
return CA_STATUS_FAILED;
}
- if (NULL != g_gattReadCharPath)
- {
- OICFree(g_gattReadCharPath);
- g_gattReadCharPath = NULL;
- }
g_gattReadCharPath = charPath;
-
}
else
{
- if (NULL != g_gattWriteCharPath)
- {
- OICFree(g_gattWriteCharPath);
- g_gattWriteCharPath = NULL;
- }
g_gattWriteCharPath = charPath;
}
CAResult_t CAStartIP()
{
+ // Specific the port number received from application.
+ caglobals.ip.u6.port = caglobals.ports.udp.u6;
+ caglobals.ip.u6s.port = caglobals.ports.udp.u6s;
+ caglobals.ip.u4.port = caglobals.ports.udp.u4;
+ caglobals.ip.u4s.port = caglobals.ports.udp.u4s;
+
CAIPStartNetworkMonitor();
#ifdef SINGLE_THREAD
uint16_t unicastPort = 55555;
static CAIPPacketReceivedCallback g_packetReceivedCallback = NULL;
-static void CAHandleNetlink();
static void CAFindReadyMessage();
#if !defined(WSA_WAIT_EVENT_0)
static void CASelectReturned(fd_set *readFds, int ret);
OIC_LOG(DEBUG, TAG, "OUT");
}
-static int CACreateSocket(int family, uint16_t *port)
+static int CACreateSocket(int family, uint16_t *port, bool isMulticast)
{
int socktype = SOCK_DGRAM;
#ifdef SOCK_CLOEXEC
OIC_LOG_V(ERROR, TAG, "IPV6_V6ONLY failed: %s", CAIPS_GET_ERROR);
}
- if (*port) // only do this for multicast ports
+ if (isMulticast && *port) // only do this for multicast ports
{
#if defined(IPV6_RECVPKTINFO)
if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof (on)))
}
else
{
- if (*port) // only do this for multicast ports
+ if (isMulticast && *port) // only do this for multicast ports
{
int on = 1;
if (-1 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, OPTVAL_T(&on), sizeof (on)))
socklen = sizeof (struct sockaddr_in);
}
- if (*port) // use the given port
+ if (isMulticast && *port) // use the given port
{
int on = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on), sizeof (on)))
#define CHECKFD(FD) \
if (FD > caglobals.ip.maxfd) \
caglobals.ip.maxfd = FD;
-#define NEWSOCKET(FAMILY, NAME) \
- caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port); \
+#define NEWSOCKET(FAMILY, NAME, MULTICAST) \
+ caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \
+ if (caglobals.ip.NAME.fd == -1) \
+ { \
+ caglobals.ip.NAME.port = 0; \
+ caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \
+ } \
CHECKFD(caglobals.ip.NAME.fd)
static void CAInitializeNetlink()
if (caglobals.ip.ipv6enabled)
{
- NEWSOCKET(AF_INET6, u6)
- NEWSOCKET(AF_INET6, u6s)
- NEWSOCKET(AF_INET6, m6)
- NEWSOCKET(AF_INET6, m6s)
+ NEWSOCKET(AF_INET6, u6, false)
+ NEWSOCKET(AF_INET6, u6s, false)
+ NEWSOCKET(AF_INET6, m6, true)
+ NEWSOCKET(AF_INET6, m6s, true)
OIC_LOG_V(INFO, TAG, "IPv6 unicast port: %u", caglobals.ip.u6.port);
}
if (caglobals.ip.ipv4enabled)
{
- NEWSOCKET(AF_INET, u4)
- NEWSOCKET(AF_INET, u4s)
- NEWSOCKET(AF_INET, m4)
- NEWSOCKET(AF_INET, m4s)
+ NEWSOCKET(AF_INET, u4, false)
+ NEWSOCKET(AF_INET, u4s, false)
+ NEWSOCKET(AF_INET, m4, true)
+ NEWSOCKET(AF_INET, m4s, true)
OIC_LOG_V(INFO, TAG, "IPv4 unicast port: %u", caglobals.ip.u4.port);
}
return CA_STATUS_FAILED;
}
}
+ return CA_STATUS_OK;
}
static void CAIPDestroyNetworkMonitorList()
{
CAInterface_t *removedifitem = (CAInterface_t *) u_arraylist_get(
g_netInterfaceList, list_index);
- if (removedifitem && removedifitem->index == ifiindex)
+ if (removedifitem && ((int)removedifitem->index) == ifiindex)
{
if (u_arraylist_remove(g_netInterfaceList, list_index))
{
static void CAInitializeTCPGlobals()
{
caglobals.tcp.ipv4.fd = -1;
- caglobals.tcp.ipv4.port = 0;
caglobals.tcp.ipv6.fd = -1;
- caglobals.tcp.ipv6.port = 0;
caglobals.tcp.selectTimeout = CA_TCP_SELECT_TIMEOUT;
caglobals.tcp.listenBacklog = CA_TCP_LISTEN_BACKLOG;
caglobals.tcp.svrlist = NULL;
{
OIC_LOG(DEBUG, TAG, "IN");
+ // Specific the port number received from application.
+ caglobals.tcp.ipv4.port = caglobals.ports.tcp.u4;
+ caglobals.tcp.ipv6.port = caglobals.ports.tcp.u6;
+
#ifndef SINGLE_THREAD
if (CA_STATUS_OK != CATCPInitializeQueueHandles())
{
}
}
+#define NEWSOCKET(FAMILY, NAME) \
+ caglobals.tcp.NAME.fd = CACreateAcceptSocket(FAMILY, &caglobals.tcp.NAME); \
+ if (caglobals.tcp.NAME.fd == -1) \
+ { \
+ caglobals.tcp.NAME.port = 0; \
+ caglobals.tcp.NAME.fd = CACreateAcceptSocket(FAMILY, &caglobals.tcp.NAME); \
+ } \
+ CHECKFD(caglobals.tcp.NAME.fd);
+
CAResult_t CATCPStartServer(const ca_thread_pool_t threadPool)
{
if (caglobals.tcp.started)
if (caglobals.server)
{
- caglobals.tcp.ipv4.fd = CACreateAcceptSocket(AF_INET, &caglobals.tcp.ipv4);
- CHECKFD(caglobals.tcp.ipv4.fd);
- caglobals.tcp.ipv6.fd = CACreateAcceptSocket(AF_INET6, &caglobals.tcp.ipv6);
- CHECKFD(caglobals.tcp.ipv6.fd);
-
+ NEWSOCKET(AF_INET, ipv4);
+ NEWSOCKET(AF_INET6, ipv6);
OIC_LOG_V(DEBUG, TAG, "IPv4 socket fd=%d, port=%d",
caglobals.tcp.ipv4.fd, caglobals.tcp.ipv4.port);
OIC_LOG_V(DEBUG, TAG, "IPv6 socket fd=%d, port=%d",
#endif
}
+CAResult_t CASetPortNumberToAssign(CATransportAdapter_t adapter,
+ CATransportFlags_t flag, uint16_t port)
+{
+ uint16_t *targetPort = 0;
+
+ if (CA_ADAPTER_IP & adapter)
+ {
+ if (CA_SECURE & flag)
+ {
+ if (CA_IPV6 & flag)
+ {
+ targetPort = &caglobals.ports.udp.u6s;
+ }
+ else if (CA_IPV4 & flag)
+ {
+ targetPort = &caglobals.ports.udp.u4s;
+ }
+ }
+ else
+ {
+ if (CA_IPV6 & flag)
+ {
+ targetPort = &caglobals.ports.udp.u6;
+ }
+ else if (CA_IPV4 & flag)
+ {
+ targetPort = &caglobals.ports.udp.u4;
+ }
+ }
+ }
+#ifdef TCP_ADAPTER
+ if (CA_ADAPTER_TCP & adapter)
+ {
+ if (CA_IPV6 & flag)
+ {
+ targetPort = &caglobals.ports.tcp.u6;
+ }
+ else if (CA_IPV4 & flag)
+ {
+ targetPort = &caglobals.ports.tcp.u4;
+ }
+ }
+#endif
+
+ if (targetPort)
+ {
+ *targetPort = port;
+ return CA_STATUS_OK;
+ }
+
+ return CA_NOT_SUPPORTED;
+}
+
+uint16_t CAGetAssignedPortNumber(CATransportAdapter_t adapter, CATransportFlags_t flag)
+{
+ OIC_LOG(DEBUG, TAG, "CAGetAssignedPortNumber");
+
+ if (CA_ADAPTER_IP & adapter)
+ {
+ if (CA_SECURE & flag)
+ {
+ if (CA_IPV6 & flag)
+ {
+ return caglobals.ip.u6s.port;
+ }
+ else if (CA_IPV4 & flag)
+ {
+ return caglobals.ip.u4s.port;
+ }
+ }
+ else
+ {
+ if (CA_IPV6 & flag)
+ {
+ return caglobals.ip.u6.port;
+ }
+ else if (CA_IPV4 & flag)
+ {
+ return caglobals.ip.u4.port;
+ }
+ }
+ }
+#ifdef TCP_ADAPTER
+ if (CA_ADAPTER_TCP & adapter)
+ {
+ if (CA_IPV6 & flag)
+ {
+ return caglobals.tcp.ipv6.port;
+ }
+ else if (CA_IPV4 & flag)
+ {
+ return caglobals.tcp.ipv4.port;
+ }
+ }
+#endif
+ return 0;
+}
+
#ifdef __ANDROID__
/**
* initialize client connection manager
}
else
{
- result = OC_STACK_OK;
-
// The error in observeResult for the request will be used when responding to this
// request by omitting the observation option/sequence number.
request->observeResult = OC_STACK_ERROR;
OIC_LOG(ERROR, TAG, "Observer Addition failed");
ehFlag = OC_REQUEST_FLAG;
+ FindAndDeleteServerRequest(request);
+ goto exit;
}
}
}
else
{
- result = OC_STACK_OK;
request->observeResult = OC_STACK_ERROR;
OIC_LOG(ERROR, TAG, "Observer Removal failed");
+ FindAndDeleteServerRequest(request);
+ goto exit;
}
}
else
*/
static void incrementSequenceNumber(OCResource * resPtr);
-/**
- * Verify the lengths of the URI and the query separately.
- *
- * @param inputUri Input URI and query.
- * @param uriLen The length of the initial URI with query.
- * @return ::OC_STACK_OK on success, some other value upon failure.
- */
-static OCStackResult verifyUriQueryLength(const char * inputUri,
- uint16_t uriLen);
-
/*
* Attempts to initialize every network interface that the CA Layer might have compiled in.
*
}
}
-OCStackResult verifyUriQueryLength(const char *inputUri, uint16_t uriLen)
-{
- char *query;
-
- query = strchr (inputUri, '?');
-
- if (query != NULL)
- {
- if((query - inputUri) > MAX_URI_LENGTH)
- {
- return OC_STACK_INVALID_URI;
- }
-
- if((inputUri + uriLen - 1 - query) > MAX_QUERY_LENGTH)
- {
- return OC_STACK_INVALID_QUERY;
- }
- }
- else if(uriLen > MAX_URI_LENGTH)
- {
- return OC_STACK_INVALID_URI;
- }
- return OC_STACK_OK;
-}
-
/**
* A request uri consists of the following components in order:
* example
*/
OCStackResult setNetworkMonitorHandler(AdapterChangedCallback adapterHandler,
ConnectionChangedCallback connectionHandler);
+
+ /**
+ * Set port number to use.
+ * @param adapter transport adapter type to assign the specified port number.
+ * @param flag transport flag information.
+ * @param port the specified port number to use.
+ * @return Returns ::OC_STACK_OK if success.
+ */
+ OCStackResult setPortNumberToAssign(OCTransportAdapter adapter,
+ OCTransportFlags flag, uint16_t port);
+
+ /**
+ * Get the assigned port number.
+ * @param adapter transport adapter type to get the opened port number.
+ * @param flag transport flag information.
+ * @return Returns currently assigned port number.
+ */
+ uint16_t getAssignedPortNumber(OCTransportAdapter adapter, OCTransportFlags flag);
}
}
static const char INVALID_ATTRIBUTE[] = "Invalid Attribute: ";
static const char INVALID_DEVICE_INFO[] = "Invalid Device Information";
static const char UNAUTHORIZED_REQUEST[] = "Unauthorized Request";
+ static const char TOO_LARGE_REQ[] = "Request Too Large";
static const char PDM_DB_NOT_INITIALIZED[] = "Provisioning DB is not initialized";
static const char DUPLICATE_UUID[] = "Duplicate UUID in DB";
static const char INCONSISTENT_DB[] = "Data in provisioning DB is inconsistent";
CAManager::ConnectionChangedCallback g_connectionHandler = nullptr;
}
+OCStackResult convertCAResultToOCResult(CAResult_t caResult)
+{
+ switch (caResult)
+ {
+ case CA_STATUS_OK:
+ return OC_STACK_OK;
+ case CA_STATUS_INVALID_PARAM:
+ return OC_STACK_INVALID_PARAM;
+ case CA_STATUS_FAILED:
+ return OC_STACK_ERROR;
+ case CA_NOT_SUPPORTED:
+ return OC_STACK_NOTIMPL;
+ default:
+ return OC_STACK_ERROR;
+ }
+}
+
void DefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled)
{
if (g_adapterHandler)
CAResult_t ret = CARegisterNetworkMonitorHandler(DefaultAdapterStateChangedHandler,
DefaultConnectionStateChangedHandler);
- switch (ret)
- {
- case CA_STATUS_OK:
- return OC_STACK_OK;
- case CA_NOT_SUPPORTED:
- return OC_STACK_NOTIMPL;
- default:
- return OC_STACK_ERROR;
- }
+ return convertCAResultToOCResult(ret);
+}
+
+OCStackResult CAManager::setPortNumberToAssign(OCTransportAdapter adapter,
+ OCTransportFlags flag, uint16_t port)
+{
+ CAResult_t ret = CASetPortNumberToAssign((CATransportAdapter_t) adapter,
+ (CATransportFlags_t) flag, port);
+
+ return convertCAResultToOCResult(ret);
+}
+
+uint16_t CAManager::getAssignedPortNumber(OCTransportAdapter adapter, OCTransportFlags flag)
+{
+ return CAGetAssignedPortNumber((CATransportAdapter_t) adapter, (CATransportFlags_t) flag);
}
return OC::Exception::INVALID_REPRESENTATION;
case OC_STACK_UNAUTHORIZED_REQ:
return OC::Exception::UNAUTHORIZED_REQUEST;
+ case OC_STACK_TOO_LARGE_REQ:
+ return OC::Exception::TOO_LARGE_REQ;
case OC_STACK_PDM_IS_NOT_INITIALIZED:
return OC::Exception::PDM_DB_NOT_INITIALIZED;
case OC_STACK_DUPLICATE_UUID:
OC_STACK_INVALID_DEVICE_INFO,
OC_STACK_INVALID_JSON,
OC_STACK_UNAUTHORIZED_REQ,
+ OC_STACK_TOO_LARGE_REQ,
OC_STACK_PRESENCE_STOPPED,
OC_STACK_PRESENCE_TIMEOUT,
OC_STACK_PRESENCE_DO_NOT_HANDLE,
OC::Exception::INVALID_DEVICE_INFO,
OC::Exception::INVALID_REPRESENTATION,
OC::Exception::UNAUTHORIZED_REQUEST,
+ OC::Exception::TOO_LARGE_REQ,
OC::Exception::PRESENCE_STOPPED,
OC::Exception::PRESENCE_TIMEOUT,
OC::Exception::PRESENCE_NOT_HANDLED,