📄 e32socketmodule.cpp
字号:
void DoCancel() {;}
#ifdef HAVE_ACTIVESCHEDULERWAIT
CActiveSchedulerWait iWait;
#endif
PyObject* iSo;
};
void CSocketAo::RunL()
{
iState = EIdle;
iXLen = iDataBuf.Length();
if (!iPyCallback) {
#ifdef HAVE_ACTIVESCHEDULERWAIT
iWait.AsyncStop();
#else
CActiveScheduler::Stop();
#endif
}
else {
PyEval_RestoreThread(PYTHON_TLS->thread_state);
PyObject* so = iSo;
PyObject* r = iCallback(iStatus.Int(), this);
PyObject* arg;
if (r)
arg = Py_BuildValue("(N)", r);
else {
PyObject *t, *v, *tb;
PyErr_Fetch(&t, &v, &tb);
PyErr_NormalizeException(&t, &v, &tb);
arg = Py_BuildValue("((OO))", t, v);
}
PyObject* cb = iPyCallback;
iPyCallback = NULL;
PyObject* tmp_r = PyEval_CallObject(cb, arg);
Py_DECREF(cb);
Py_XDECREF(tmp_r);
Py_XDECREF(arg);
Py_XDECREF(so);
PyEval_SaveThread();
}
}
class CSocketEngine : public CBase
{
friend class SSLEngine;
public:
CSocketEngine():iPort(-1),iAdvertiser(NULL) {;}
~CSocketEngine() {
// At this point these invariants should hold:
// iReadAo.iState == EIdle
// iReadAo.iPyCallback == NULL
// iWriteAo.iState == EIdle
// iWriteAo.iPyCallback == NULL
iSocket.Close();
if (iAdvertiser) {
iAdvertiser->StopAdvertisingL();
delete iAdvertiser;
}
}
TUint GetProtoInfo() {
TProtocolDesc protocol;
TInt error = iSocket.Info(protocol);
if (error != KErrNone)
return error;
return protocol.iProtocol;
}
TInt iPort;
RSocket iSocket;
CSocketAo iReadAo;
CSocketAo iWriteAo;
CObjectExchangeServiceAdvertiser* iAdvertiser;
};
/* Python APIs */
#define Socket_type ((PyTypeObject*)SPyGetGlobalString("SocketType"))
/*
* No class members here as they do not get
* properly initialized by PyObject_New() !!!
*/
struct Socket_object {
PyObject_VAR_HEAD
CSocketEngine* SE;
int ob_is_closed;
int ob_is_connected;
unsigned int ob_proto;
};
extern "C" {
static void Socket_dealloc(Socket_object *so)
{
delete so->SE;
so->SE = NULL;
PyObject_Del(so);
}
void socket_mod_cleanup()
{
TStaticData* sd = GetServer();
if(sd!=NULL){
if(sd->apo!=NULL){
sd->apo->started = EFalse;
ap_stop(sd->apo,NULL);
Py_DECREF(sd->apo);
sd->apo = NULL;
}
sd->rss.Close();
delete static_cast<TStaticData *>(Dll::Tls());
Dll::SetTls(NULL);
}
}
}
static void str2Hex(const TDesC &aBTHexAddr, TBuf8<6> &aBTAddress)
{
/* convert string into Hex address */
for (TInt i=0; i<6; i++)
{
TInt j =0;
if (i!=0)
j = i +(i*2);
TLex hexValue(aBTHexAddr.Mid(j, 2));
TUint8 n;
hexValue.Val(n, EHex);
aBTAddress.Append(TChar(n));
}
return;
}
static TInt set_symbian_inet_addr(TInetAddr &aInetAddr, char* str, int length, int port)
{
TBuf<MaxIPAddrLength> address;
address.FillZ(MaxIPAddrLength);
address.Copy((TPtrC8((TUint8*)str, length)));
if (port)
aInetAddr.SetPort(port);
return aInetAddr.Input(address);
}
static void set_symbian_bt_addr(TBTSockAddr &address, char* str, int length, int port)
{
TBuf<MaxIPAddrLength+1> aBTHexAddr;
aBTHexAddr.FillZ(MaxIPAddrLength+1);
aBTHexAddr.Copy((TPtrC8 ((TUint8*)str, length)));
TBuf8<6> aBTAddress;
str2Hex(aBTHexAddr, aBTAddress);
address.SetBTAddr(aBTAddress);
if (port != 0)
address.SetPort(port);
}
static PyObject* create_socket_object()
{
Socket_object *so = PyObject_New(Socket_object, Socket_type);
if (so == NULL)
return PyErr_NoMemory();
so->SE = new CSocketEngine();
if (so->SE == NULL) {
PyObject_Del(so);
return PyErr_NoMemory();
}
so->ob_is_closed = 0;
so->ob_is_connected = 0;
return (PyObject*) so;
}
static int KErrToErrno(TInt aError)
{
int i;
// FIXME Replace unreadable magic numbers with symbolic error codes.
switch(aError) {
case (-1):
i = ENOENT;
break;
case (-3):
i = EINTR;
break;
case (-4):
i = ENOMEM;
break;
case (-5):
i = ENOSYS;
break;
case (-6):
case (-28):
i = EINVAL;
break;
case (-9):
case (-10):
i = ERANGE;
break;
case (-11):
i = EEXIST;
break;
case (-12):
i = ENOENT;
break;
case (-13):
case (-15):
case (-25):
case (-36):
i = EPIPE;
break;
case (-14):
i = EACCES;
break;
case (-16):
i = EBUSY;
break;
case (-21):
case (-22):
i = EACCES;
break;
case (-24):
i = ENODEV;
break;
case (-26):
case (-43):
i = ENOSPC;
break;
case (-29):
case (-30):
case (-31):
case (-32):
i = ECOMM;
break;
case (-33):
i = ETIMEDOUT;
break;
case (-34):
i = ECONNREFUSED;
break;
case (-41):
case (-42):
i = EDOM;
break;
default:
i = 0;
break;
}
return i;
}
static PyObject* _mod_dict_get_s(char* s)
{
PyInterpreterState *interp = PyThreadState_Get()->interp;
PyObject* m = PyDict_GetItemString(interp->modules, "e32socket");
return PyDict_GetItemString(PyModule_GetDict(m), s);
}
static PyObject *
PySocket_Err(TInt aError)
{
PyObject *v;
char *s;
if (aError == KErrPython)
return NULL;
int i = KErrToErrno(aError);
if (i == 0)
s = "Error";
else
s = strerror(i);
v = Py_BuildValue("(is)", i, s);
if (v != NULL) {
PyErr_SetObject(_mod_dict_get_s("error"), v);
Py_DECREF(v);
}
return NULL;
}
static PyObject *
PySocket_Err(char* aMsg)
{
PyErr_SetString(_mod_dict_get_s("error"), aMsg);
return NULL;
}
/* for Host resolver */
static PyObject *
PyGAI_Err(TInt aError)
{
PyObject *v;
int error = KErrToErrno(aError);
v = Py_BuildValue("(is)", error, "getaddrinfo failed");
if (v != NULL) {
PyErr_SetObject(_mod_dict_get_s("gaierror"), v);
Py_DECREF(v);
}
return NULL;
}
#define RETURN_SOCKET_ERROR_OR_PYNONE(error) \
if (error != KErrNone)\
return PySocket_Err(error);\
else {\
Py_INCREF(Py_None);\
return Py_None;\
}
#define E32SOCKET_CHECK
#ifdef E32SOCKET_CHECK
#define CHECK_NOTCLOSED(op) \
if (op->ob_is_closed)\
return PySocket_Err("Attempt to use a closed socket")
#define CHECK_NOTCLOSED_NOTREADBUSY(op) \
if (op->ob_is_closed)\
return PySocket_Err("Attempt to use a closed socket");\
if (op->SE->iReadAo.iState == CSocketAo::EBusy)\
return PySocket_Err(KErrInUse)
#define CHECK_NOTCLOSED_NOTWRITEBUSY(op) \
if (op->ob_is_closed)\
return PySocket_Err("Attempt to use a closed socket");\
if (op->SE->iWriteAo.iState == CSocketAo::EBusy)\
return PySocket_Err(KErrInUse)
#define VERIFY_PROTO(c) \
if (!(c)) return PySocket_Err("Bad protocol")
#else
#define CHECK_NOTCLOSED(op)
#define CHECK_NOTCLOSED_NOTREADBUSY(op)
#define CHECK_NOTCLOSED_NOTWRITEBUSY(op)
#define VERIFY_PROTO(c)
#endif /* E32SOCKET_CHECK */
extern "C" PyObject *
new_Socket_object(PyObject* /*self*/, PyObject *args)
{
TUint family;
TUint type;
TInt protocol = -1;
AP_object *apo = NULL;
TStaticData* sd = GetServer();
if(sd==NULL){
return NULL;
}
if (!PyArg_ParseTuple(args, "iiiO", &family, &type, &protocol, &apo)) {
return NULL;
}
if (family == KAfInet) {
if (type == KSockStream) {
if (protocol && (protocol != (TInt)KProtocolInetTcp))
return PySocket_Err("Bad protocol");
else
protocol = KProtocolInetTcp;
}
else if (type == KSockDatagram) {
if (protocol && (protocol != (TInt)KProtocolInetUdp))
return PySocket_Err("Bad protocol");
else
protocol = KProtocolInetUdp;
}
else
return PySocket_Err("Bad socket type");
}
else if (family == KAfBT) {
if (type == KSockStream) {
if ((protocol == (TInt)KRFCOMM) || (protocol == 0))
protocol = KRFCOMM;
else
return PySocket_Err("Bad protocol");
}
else
return PySocket_Err("Bad socket type");
}
else
return PySocket_Err("Unknown address family");
Socket_object* socket = (Socket_object*) create_socket_object();
if (socket == NULL)
return NULL;
socket->ob_proto = protocol;
TInt error = KErrNone;
if (family == KAfInet)
{
if (apo != NULL && (PyObject*)apo != Py_None)
{
if (!ap_start(apo,NULL)) {
Socket_dealloc(socket);
PyErr_SetString(PyExc_RuntimeError, "Couldn't start RConnection");
return NULL;
}
else {
error = socket->SE->iSocket.Open(sd->rss, family, type, protocol, *apo->connection);
}
}
else if (sd->apo != NULL && (PyObject*)sd->apo!=Py_None)
{
if (!ap_start(sd->apo,NULL)) {
Socket_dealloc(socket);
PyErr_SetString(PyExc_RuntimeError, "Couldn't start RConnection");
return NULL;
}
else {
error = socket->SE->iSocket.Open(sd->rss, family, type, protocol, *sd->apo->connection);
}
}
else {
error = socket->SE->iSocket.Open(sd->rss, family, type, protocol);
}
}
else if (family == KAfBT) {
error = socket->SE->iSocket.Open(sd->rss, KServerTransportName);
}
if (error != KErrNone) {
if (apo != NULL && (PyObject*)apo != Py_None) {
ap_stop(apo, NULL);
delete apo;
}
Socket_dealloc(socket);
return PySocket_Err(error);
}
return (PyObject*) socket;
}
extern "C" PyObject *
socket_accept_return(TInt aError, CSocketAo* aOp);
extern "C" PyObject *
socket_accept(Socket_object* self, PyObject *args)
{
CHECK_NOTCLOSED_NOTREADBUSY(self);
VERIFY_PROTO((self->ob_proto == KRFCOMM) ||
(self->ob_proto == KProtocolInetTcp));
PyObject* c = NULL;
TStaticData* sd = NULL;
if (!PyArg_ParseTuple(args, "|O", &c))
return NULL;
if (c == Py_None)
c = NULL;
else if (c && !PyCallable_Check(c)) {
PyErr_BadArgument();
return NULL;
}
CSocketEngine* new_SE = new CSocketEngine();
if (!new_SE)
return PyErr_NoMemory();
sd = GetServer();
if(sd==NULL){
return NULL;
}
TInt error = new_SE->iSocket.Open(sd->rss);
if (error != KErrNone) {
delete new_SE;
return PySocket_Err(error);
}
self->SE->iReadAo.iData[0] = (TAny*)new_SE;
self->SE->iReadAo.iCallback = &socket_accept_return;
self->SE->iReadAo.iPyCallback = c;
self->SE->iSocket.Accept(new_SE->iSocket, self->SE->iReadAo.iStatus);
return self->SE->iReadAo.HandleReturn((PyObject*)self);
}
extern "C" PyObject *
socket_accept_return(TInt aError, CSocketAo* aOp)
{
CSocketEngine* new_SE = (CSocketEngine*)aOp->iData[0];
if (aError != KErrNone) {
delete new_SE;
return PySocket_Err(aError);
}
TProtocolDesc protocol;
TInt error = new_SE->iSocket.Info(protocol);
if (error != KErrNone) {
delete new_SE;
return PySocket_Err(error);
}
Socket_object* new_so = PyObject_New(Socket_object, Socket_type);
if (!new_so) {
delete new_SE;
return PyErr_NoMemory();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -