summaryrefslogtreecommitdiff
path: root/plugins/iwmx.h
blob: f3bc07b41816a6d949da6ec2adba83f98830eea8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

/* Fix source compat brakage from 1.4 to 1.5...*/
#ifndef HAVE_WIMAX_API_DEVICE_ID
typedef struct WIMAX_API_DEVICE_ID WIMAX_API_DEVICE_ID;
#endif

#ifndef HAVE_WIMAX_API_CONNECTED_NSP_INFO
typedef struct WIMAX_API_CONNECTED_NSP_INFO WIMAX_API_CONNECTED_NSP_INFO;
#endif

#ifndef HAVE_WIMAX_API_NSP_INFO_EX
typedef struct WIMAX_API_NSP_INFO_EX WIMAX_API_NSP_INFO_EX;
#endif

#ifndef HAVE_WIMAX_API_HW_DEVICE_ID
typedef struct WIMAX_API_HW_DEVICE_ID WIMAX_API_HW_DEVICE_ID;
#endif


/*
 *
 * The plugin is broken in two main parts: the glue to connman
 * (iwmx_cm_*() functions) and the glue to the libiWmxSdk (iwmx_sdk_*()
 * functions). They connect using a well defined interface.
 *
 * The plugin is state based and operates reactively to state
 * transtitions on the WiMAX device or to user requests, even from
 * external control tools that are not aware of connman.
 *
 * When the user requests connman to do something, it goes into a call
 * implemented by the 'struct connman_driver iwmx_cm_driver' (or
 * iwmx_cm_network_driver) that will instruct libiWmxSDK to change the
 * device's state.
 *
 * When the device changes state, a state change callback is sent back
 * by libiWmxSDK, which gets fed to iwmx_cm_state_change(), which
 * evaluates the state change and updates connman's internal state in
 * response.
 *
 * This allows the device to be also controlled by external tools
 * without driving connman out of state.
 *
 * Device's state changes can be caused through:
 *
 *  - connman (by user request)
 *
 *  - any other external utility (eg: WmxSDK's wimaxcu)
 *
 *  - external stimuli: network connection broken when going out of
 *    range
 *
 * Functions named __*() normally indicate that require locking. See
 * their doc header.
 *
 * ENUMERATION
 *
 * When we receive a normal probe request [iwmx_cm_probe()] from
 * connman, we ignore it (we can tell based on the connman device
 * having NULL data).
 *
 * The plugin has registered with the WiMAX Network Service and it
 * will listen to its device add/rm messages [iwmx_sdk_addremove_cb()]
 * and use that to create a  device [iwmx_sdk_dev_add()] which will be
 * registered with connman. [iwmx_cm_dev_add()]. Then connman will
 * enumerate the device, call again iwmx_cm_probe() and at this time,
 * we'll recognize it, pass through iwmx_sdk_setup() and complete the
 * probe process.
 *
 * If the daemon dies, in theory the plugin will realize and remove
 * the WiMAX device.
 */

struct wmxsdk {
	WIMAX_API_DEVICE_ID device_id;
	struct connman_device *dev;

	GStaticMutex network_mutex;

	WIMAX_API_DEVICE_STATUS status;
	GMutex *status_mutex;

	/*
	 * nw points to the network we are connected to. connecting_nw
	 * points to the network we have requested to connect.
	 */
	GMutex *connect_mutex;
	struct connman_network *connecting_nw, *nw;

	char name[100];
	char ifname[16];
};

/* Initialize a [zeroed] struct wmxsdk */
static inline void wmxsdk_init(struct wmxsdk *wmxsdk)
{
	g_static_mutex_init(&wmxsdk->network_mutex);

	wmxsdk->status = WIMAX_API_DEVICE_STATUS_UnInitialized;
	wmxsdk->status_mutex = g_mutex_new();
	g_assert(wmxsdk->status_mutex);

	wmxsdk->connect_mutex = g_mutex_new();
	g_assert(wmxsdk->connect_mutex);
}

/* Misc utilities */
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
#define container_of(pointer, type, member)				\
({									\
	type *object = NULL;						\
	size_t offset = (void *) &object->member - (void *) object;	\
	(type *) ((void *) pointer - offset);				\
})

/* Misc values */
enum {
	/**
	 * Time we wait for callbacks: 5s
	 *
	 * I know, it is huge, but L4 and the device sometimes take
	 * some time, especially when there is crypto involved.
	 */
	IWMX_SDK_L4_TIMEOUT_US = 5 * 1000 * 1000,

	/*
	 * WARNING!!!!!
	 *
	 * ONLY ONE DEVICE SUPPORTED
	 *
	 * - on removal, there is no way to know which device was
	 *   removed (the removed device is removed from the list and
	 *   the callback doesn't have any more information than the
	 *   index in the list that getlistdevice would return -- racy
	 *   as hell).
	 *
	 * - on insertion, there is not enough information provided.
	 */
	IWMX_SDK_DEV_MAX = 1,
};

struct connman_network *__iwmx_cm_network_available(
			struct wmxsdk *wmxsdk, const char *station_name,
			const void *sdk_nspname, size_t sdk_nspname_size,
								int strength);

struct connman_network *iwmx_cm_network_available(
			struct wmxsdk *wmxsdk, const char *station_name,
			const void *sdk_nspname, size_t sdk_nspname_size,
								int strength);

WIMAX_API_DEVICE_STATUS iwmx_cm_status_get(struct wmxsdk *wmxsdk);
void __iwmx_cm_state_change(struct wmxsdk *wmxsdk,
					WIMAX_API_DEVICE_STATUS __new_status);
void iwmx_cm_state_change(struct wmxsdk *wmxsdk,
					WIMAX_API_DEVICE_STATUS __new_status);

int iwmx_sdk_connect(struct wmxsdk *wmxsdk, struct connman_network *nw);
int iwmx_sdk_disconnect(struct wmxsdk *wmxsdk);
struct connman_network *__iwmx_sdk_get_connected_network(struct wmxsdk *wmxsdk);
const char *iwmx_sdk_dev_status_to_str(WIMAX_API_DEVICE_STATUS status);
int iwmx_sdk_rf_state_set(struct wmxsdk *wmxsdk, WIMAX_API_RF_STATE rf_state);
WIMAX_API_DEVICE_STATUS iwmx_sdk_get_device_status(struct wmxsdk *wmxsdk);
int iwmx_sdk_setup(struct wmxsdk *wmxsdk);
void iwmx_sdk_remove(struct wmxsdk *wmxsdk);
int iwmx_sdk_scan(struct wmxsdk *wmxsdk);
int iwmx_sdk_api_init(void);
void iwmx_sdk_api_exit(void);